On Sun, 24 Nov 2013 11:30:14 +0100, Antoon Pardon wrote: > Foo.foo() is legal here. So Foo.foo is callable.
Incorrect. Foo.foo() is legal for *any* identifiers Foo and foo. Since Python is an extremely dynamic language, the compiler cannot (easily, or at all) prohibit "illegal" combinations. The only combinations which are illegal are those which are not legal identifier, e.g.: while.spam abc$xyz.eggs Otherwise, any pair of legal identifiers are legal and will be accepted by the compiler. Only at runtime does the lookup succeed or fail: str.length # likely to fail, unless str has been shadowed str.find # likely to succeed, unless str has been shadowed If the lookup has succeeded, then and only then does a second lookup occur, namely: type(str.find).__call__ and if that succeeds it is called. It isn't helpful to talk about function or method calls being "legal" or "illegal" in Python, since such things are normally determined in terms of *success* or *failure*, not permitted versus prohibited. Either the full chain of lookups and function call will succeed, or something will raise an exception and it will fail. > Foo.foo() being legal and Foo.foo not being callable is IMO a bug in > python. No matter what explanation you have for the behaviour. I don't know why you keep going on about this point, since this is NOT the behaviour the original poster is talking about. With foo decorated as a staticmethod in class Foo, Foo.foo *is* callable. It takes 30 seconds to try it yourself: py> class Foo(object): # inherit from object necessary in Python 2 ... @staticmethod ... def foo(): ... return "Success!" ... py> py> Foo.foo() 'Success!' py> Foo().foo() 'Success!' This is not what the OP is talking about. Try this instead: py> Foo.__dict__['foo']() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'staticmethod' object is not callable What's going on here? Let's have a look: py> Foo.__dict__['foo'] <staticmethod object at 0x9d83194> py> Foo.foo <function foo at 0x9d80294> You CANNOT understand this behaviour without understanding the descriptor protocol, which is *fundamental* to Python, and has been since Python 2.2. Regular instance methods, class methods, static methods and properties are all defined in terms of descriptors. Trying to understand them without knowledge of descriptors is like trying to understand generators and iterators without knowledge of StopIteration -- you can go only so far before you get stuck and confused. The OP discovered that you can call a regular function inside a class body, outside of a method, during the class statement: class MyClass: def function(): return "stuff" attr = function() This works, but then you can't call MyClass().function() as it will raise. So the OP tried making it a staticmethod: class MyClass: @staticmethod def function(): return "stuff" attr = function() but that fails, because *staticmethod instances are not callable*. They are descriptors. Only after the descriptor protocol gets a chance to run do you get a callable function. *This is not a bug.* Making staticmethod instances callable is a feature enhancement, not a bug fix. Or you could just define your own callable- staticmethod descriptor, it's easy enough to do. -- Steven -- https://mail.python.org/mailman/listinfo/python-list