On Mon, 19 May 2008 13:53:31 -0700, [EMAIL PROTECTED] wrote: > On 17 mai, 11:50, Ivan Illarionov <[EMAIL PROTECTED]> wrote: >> On Sat, 17 May 2008 02:33:13 -0300, Gabriel Genellina wrote: >> > En Sat, 17 May 2008 01:01:50 -0300, Ivan Illarionov >> > <[EMAIL PROTECTED]> escribió: >> >> >> After re-reading "Python is not Java" I finally came to conclusion >> >> that classmethods in Python are a very Bad Thing. >> >> >> I can't see any use-case of them that couldn't be re-written more >> >> clearly with methods of metaclass or plain functions. >> >> > A good use case for class methods are alternate constructors, like >> > dict.from_keys. I don't think an alternate constructor would be more >> > clear being a method of the metaclass - actually it belongs to the >> > class itself, not to its metaclass. >> > Metaclass methods are harder to find; they don't show in >> > dir(instance) nor dir(class). >> > Also the resolution order is harder to grasp for metaclasses - but >> > this may be just lack of usage from my part... >> >> >> They have the following issues: >> >> 1. You mix instance-level and class-level functionality in one place >> >> making your code a mess. >> >> > Not necesarily; some classmethods are naturally tied to the class >> > itself, not to the metaclass (like the constructor example above). >> > But yes, *some* classmethods could be written as methods of their >> > metaclass instead - but that doesn't always make sense. >> >> >> 2. They are slower than metaclass methods or plain functions. >> >> > Hu? How did you come to that? >> > I've done a small test and a class method wins by a very minuscule >> > but consistent advantage over a metaclass method: >> >> > class A(object): >> > color = "red" >> >> > @classmethod >> > def foo(cls, x): >> > return getattr(cls, x) >> >> > class MetaB(type): >> > def foo(self, x): >> > return getattr(self, x) >> >> > class B(object): >> > __metaclass__ = MetaB >> > color = "red" >> >> > C:\TEMP>python -m timeit -s "from meta3 import A,B;a,b=A(),B()" >> > "A.foo('color')" >> > 1000000 loops, best of 3: 1.19 usec per loop >> >> > C:\TEMP>python -m timeit -s "from meta3 import A,B;a,b=A(),B()" >> > "B.foo('color')" >> > 1000000 loops, best of 3: 1.2 usec per loop >> >> How did I come to this:http://code.djangoproject.com/changeset/7098 >> >> I measured this and there was a marginal speed increase when >> classmethods wher moved to metaclass. > > IIRC (please correct me if I'm wrong), this part of code is only called > when the class is created - in which case it makes sense to move it > where it belongs, ie to the metaclass. This is by no mean a use case for > classmethods.
Yes, this is not the use case for class methods, but they where used there. The whole point of my post was to say that classmethods are used in a wrong way too often and most of Python programmers don't know that the same thing can be implemented with metaclass methods. -- Ivan -- http://mail.python.org/mailman/listinfo/python-list