What Are Class Descriptors?
Why does the following snippet not work?
class Document:
@classmethod
def noop(cls):
pass
@staticmethod
def hello():
pass
def foo(self):
pass
assert Document.foo == Document.__dict__.get('foo'), "this works"
assert Document.noop == Document.__dict__.get('noop'), "this fails"
assert Document.hello == Document.__dict__.get('hello'), "this fails"
The problem is that classmethod
and staticmethod
are class descriptors. When we call __getattribute__
via Document.noop
, the classmethod
decorator transforms the noop
function to be bound to Document
. However, Document.__dict__.get('foo')
doesn’t evaluate classmethod
and simply returns the wrapped function.