RE: Python-Dev digest, Vol 1 #1324 - 16 msgs
Thomas Heller: PS: I find it strange that everyone so far seems to be against it.
Tim Peters: I didn't get that sense yet. I did get the sense they're not actively *for* it yet, and the questions asked so far explain why: What does it buy us?
Greg Wilson: I'd really like class methods so that my classes can carry their factory methods around with them, and so that these factories can be selectively overridden in derived classes. I have machinery to do all of this using freestanding functions, but it's clumsy and error-prone. Of course, so is a lot of my code... :-)
[Greg Wilson]
I'd really like class methods so that my classes can carry their factory methods around with them, and so that these factories can be selectively overridden in derived classes.
Without a concrete example it's risky to guess, but that sounds more like class static (in C++ terms) methods to me. "class methods" in *this* thread is being used in a Smalltalk sense (because it's Thomas Heller's thread, and he made clear that he doesn't want C++-style class statics). And, yes, without a concrete example, it's risky to guess what that means too <wink>. expecting-a-long-thread-full-of-misinterpreted-words-ly y'rs - tim
Tim Peters <tim.one@home.com>:
"class methods" in *this* thread is being used in a Smalltalk sense (because it's Thomas Heller's thread, and he made clear that he doesn't want C++-style class statics).
It sounds like he wants not just class methods, but to unify classes and instances the way they are in Smalltalk. That's not necessary *just* to get class methods. For instance, suppose you could write class Foo: def ftang(class c, x, y, z); ... where the 'class' keyword in the argument list would say that it is to be a class method. That special form of the def statement would create an 'unbound class method' object, whose first argument would be filled in with the class object when Foo.ftang was accessed. Hmmm... might write a PEP on that! Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+
Tim Peters <tim.one@home.com>:
"class methods" in *this* thread is being used in a Smalltalk sense (because it's Thomas Heller's thread, and he made clear that he doesn't want C++-style class statics).
Well, I shouldn't have talked about C++ static methods, because I'm not too familiar with them. Here's what I want: Assume C is a class with a class-method mth, and D is 'class D(C): pass'. C.mth() should call this method, which in turn (automatically) receives C itself as the first parameter. D.mth() should call this method, which in turn (automatically) receives D itself as the first parameter.
It sounds like he wants not just class methods, but to unify classes and instances the way they are in Smalltalk.
The metaclass approach is one solution, not neccessarily the best.
That's not necessary *just* to get class methods. For instance, suppose you could write
class Foo:
def ftang(class c, x, y, z); ...
where the 'class' keyword in the argument list would say that it is to be a class method. That special form of the def statement would create an 'unbound class method' object, whose first argument would be filled in with the class object when Foo.ftang was accessed.
Donald Beaudry's objectmodule uses the metaclass hook to provide class methods. I like the resulting syntax very much: He uses an 'inner class' with the special name '__class__' to specify class methods: class Object(object.base): class __class__: def class_method(self): pass def normal_method(self): pass If I understand correctly (objectmodule does not run under 1.5.2 or later), an instance of __class__ will become the metaclass of Object, and __class__'s methods will become class methods of Object. I've played a little bit with metaclasses in pure python (it is faster this way), and have an implementation with the same syntax where __class__ is never instantiated, and simply acts as a function container. Addendum: Additionaly to class methods, I would like to have 'magic' class methods, maybe named __class_init__ and __class_getattr__. Easy to guess what they should do...
Hmmm... might write a PEP on that!
Me too. Thomas
"Thomas Heller" <thomas.heller@ion-tof.com> wrote,
Donald Beaudry's objectmodule uses the metaclass hook to provide class methods. I like the resulting syntax very much:
Thank you. I like it too, especially because MyClass.__class__ returns what *I* would expect ;) and the source reflects that too.
If I understand correctly (objectmodule does not run under 1.5.2 or later), an instance of __class__ will become the metaclass of Object, and __class__'s methods will become class methods of Object.
That's correct. I currently use objectmodule on 1.5.2. I would not be surprised if it doesnt work on newer versions though as I have never tried it there. Perhaps you found an out-of-date version, or perhaps I never sent out a newer version. Regardless, I'd be happy to get you a version that works with 1.5.2 (or upload one somewhere for more public consumption)
I've played a little bit with metaclasses in pure python (it is faster this way), and have an implementation with the same syntax where __class__ is never instantiated, and simply acts as a function container.
Ah but with the object module, it does get instantiated. In fact, __class__ is derived (implicitly) from the __class__ of the containing base class. Inheritance works as expected.
Addendum: Additionaly to class methods, I would like to have 'magic' class methods, maybe named __class_init__ and __class_getattr__. Easy to guess what they should do...
Objectmodule provides for that as well. Just define __init__, __getattr__, etc., inside the __class__ definition. There is even and __new__ which is responsible for controling the "memory allocation" of instances. This is useful for, amoung other things, singletons.
Hmmm... might write a PEP on that!
Me too.
...gone are the days when a simple email to Guido was all it took to get a proposal going ;) -- Donald Beaudry Ab Initio Software Corp. 201 Spring Street donb@init.com Lexington, MA 02421 ...So much code, so little time...
"Thomas Heller" <thomas.heller@ion-tof.com> wrote,
Donald Beaudry's objectmodule uses the metaclass hook to provide class methods. I like the resulting syntax very much:
Thank you. I like it too, especially because MyClass.__class__ returns what *I* would expect ;) and the source reflects that too.
If I understand correctly (objectmodule does not run under 1.5.2 or later), an instance of __class__ will become the metaclass of Object, and __class__'s methods will become class methods of Object.
That's correct. I currently use objectmodule on 1.5.2. I would not be surprised if it doesnt work on newer versions though as I have never tried it there. Perhaps you found an out-of-date version, or perhaps I never sent out a newer version. Regardless, I'd be happy to get you a version that works with 1.5.2 (or upload one somewhere for more public consumption)
Sure I would be interested: Please send it. Thanks for the description, I've (eagerly) read everything I found in objectmodule-0.9.tar.gz - except I found that it would be easier to step in a debugger through the c-code, which turned out to fail. BTW: I just exchanged a couple of emails with Just van Rossum, who had something very similar to yours (but you may know this already). He pointed me to some discussions in '98 in the types-sig archives. He proposed an additional hook in ceval.c (which would probably break objectmodule). I've attached his proposed patch below. Thomas + /* __BEGIN__ of Just's Hook + + Guido's metahook is defined as follows: + - if one of the bases has a __class__ attribute (but is + itself not a class!), call that thing with (name, + bases, methods) + In addition I propose almost the opposite: + - if the "methods" dict (__dict__ from the Python + perspective) has a __class__ key, call that thing with + (name, bases, methods) + + This means that metaclasses are not special anymore, and + you have to specify a metaclass *explicitly* to get meta + behaviour. Example: + + class Foo: + __class__ = MyMetaClass + + as apposed to + + MyMeta = MyMetaClass("MyMeta", (), {}) + + class Foo(MyMeta): pass + + as it is with Guido's hook. + + Reasons for this new hook: + - Guido's hook abuses inheritance syntax, making it + impossible to inherit from metaclasses without special + trickery. + - implementing Meta stuff seems cleaner. Or maybe it's + just me... + + At first I thought Guido's hook would not be compatible with + mine, but they work together beautifully: inheritance works + just like you would expect. + */ + { + PyObject *callable = NULL; + callable = PyDict_GetItemString(methods, "__class__"); + if (callable) { + PyObject *args; + PyObject *newclass = NULL; + PyDict_DelItemString(methods, "__class__"); + args = Py_BuildValue( + "(OOO)", name, bases, methods); + if (args != NULL) { + newclass = PyEval_CallObject( + callable, args); + Py_DECREF(args); + } + return newclass; + } else { + PyErr_Clear(); + } + } + /* __END__ of Just's Hook */ n = PyTuple_Size(bases); for (i = 0; i < n; i++) { PyObject *base = PyTuple_GET_ITEM(bases, i); if (!PyClass_Check(base)) { /* Call the base's *type*, if it is callable.
Greg Ewing writes:
class Foo:
def ftang(class c, x, y, z); ...
I like this syntax better that the others. While it requires that a single namespace is used for class and normal methods, I think that is a good thing -- we don't *want* overlapping sets of names! -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> PythonLabs at Digital Creations
"Fred L. Drake, Jr." <fdrake@acm.org> wrote,
Greg Ewing writes:
class Foo:
def ftang(class c, x, y, z); ...
I like this syntax better that the others. While it requires that a single namespace is used for class and normal methods, I think that is a good thing -- we don't *want* overlapping sets of names!
But... we have overlaping names! __init__ is just one example. Further, that only works for methods. How should class attributes be distinguished? Perhaps you dont want them. Should a decision be made to go down this road, a big choice lies ahead. Are class objects "special" or are they simply instances of a different class? Because I didnt want to make a whole pile of decisions regarding the "specialness" of class objects, I chose to make the one decision that class object's only distinction from other objects is that they are instances of a different class. This is, afterall, how all objects are distinguished. -- Donald Beaudry Ab Initio Software Corp. 201 Spring Street donb@init.com Lexington, MA 02421 ...Will hack for sushi...
participants (6)
-
Donald Beaudry
-
Fred L. Drake, Jr.
-
Greg Ewing
-
Greg Wilson
-
Thomas Heller
-
Tim Peters