@property; @classmethod; def f()
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sun Jan 2 02:18:48 EST 2011
On Sat, 01 Jan 2011 17:55:10 -0800, K. Richard Pixley wrote:
> Can anyone explain to me why this doesn't work?
>
> class Foo(object):
> @property
> @classmethod
> def f(cls):
> return 4
What does "doesn't work" mean? It works for me:
>>> class Foo(object):
... @property
... @classmethod
... def f(cls):
... return 4
...
>>>
There is no syntax error, the class is created, it works fine. What were
you expecting to happen?
If you instantiate the class and try accessing the property, you get the
expected runtime error:
>>> x = Foo()
>>> x.f
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'classmethod' object is not callable
(Admittedly, *you* might not have expected it, but nevertheless...)
property() expects a callable object, not a classmethod object, so
naturally it fails. Admittedly, it's a little unexpected that
classmethods aren't callable, but they're not:
>>> classmethod(lambda x: 42)()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'classmethod' object is not callable
Don't confuse the classmethod object with a class method (note the
space!). Class methods are what you get once the descriptor mechanism
kicks into action behind the scenes. classmethod objects are the
descriptors that create class methods (note space) when required:
>>> cm = classmethod(lambda x: 42).__get__(Spam) # descriptor protocol
>>> cm
<bound method type.<lambda> of <class 'type'>>
>>> cm()
42
> I mean, I think it seems to be syntactically clear what I'm trying to
> accomplish. What am I missing?
An understanding of the dark and murky waters of descriptor black magic :)
http://docs.python.org/howto/descriptor.html
(It's not really that dark and murky. It's actually amazingly simple.)
My recommendation is, forget the classmethod. A combination of property
with class attributes and self.__class__ will get you what you want.
Otherwise, just create your own descriptor object. The How To above shows
pure-python versions of classmethod and staticmethod.
--
Steven
More information about the Python-list
mailing list