[Python-Dev] Callable, non-descriptor class attributes.

Steven D'Aprano steve at pearwood.info
Sun Mar 13 02:27:46 CET 2011


Thomas Wouters wrote:

> I would much rather loudly warn people to fix their code, instead of forcing
> other implementations (and, more importantly to me personally, future
> CPython changes :) to deal with the distinction forever. But if we declare a
> wrapper to be the right way to deal with this, let's at least do it right,
> not half-assed again. And if we do add the nondescriptor wrapper for that, I
> wonder if there are still cases where staticmethods should be callable; it
> seems to me it would have no real benefit, and it would lure people into a
> false sense of security when mistakenly using staticmethod as the wrapper
> (which is, after all, a lot more visible.)


The primary benefit to my mind is two avoid breaking the Principle of 
Least Astonishment (PLA). Given:

class C(object):
     @staticmethod
     def spam():
         pass

spam looks like a callable. It is a callable when referenced via C.spam 
or C().spam. But inside the class block, it isn't callable. That comes 
as an unpleasant surprise to anyone who, like me, has tried to use a 
staticmethod as a helper function during class construction:

class C(object):
     @staticmethod
     def spam():
         pass
     result = spam()

That something that looks like a function fails to be callable violates 
PLA. There are work-arounds, but none of them are pretty or obvious:

     # the underlying function doesn't seem to be available directly
     result = spam.__get__(object())


or something like this:

class C(object):
     def spam():
         pass
     result = spam()
     spam = staticmethod(spam)

Making staticmethod callable would, in my opinion, be the obvious way to 
do it.


-- 
Steven



More information about the Python-Dev mailing list