Classmethods are evil
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Sat May 17 01:33:13 EDT 2008
En Sat, 17 May 2008 01:01:50 -0300, Ivan Illarionov
<ivan.illarionov at gmail.com> 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
--
Gabriel Genellina
More information about the Python-list
mailing list