Steven Bethard wrote: > (For anyone else out there reading who doesn't already know this, > Steven D'Aprano's comments are easily explained by noting that the > __get__ method of staticmethod objects returns functions, and classes > always call the __get__ methods of descriptors when those descriptors > are class attributes:
Steven D'Aprano wrote: > Why all the indirection to implement something which is, conceptually, > the same as an ordinary function? While I wasn't around when descriptors and new-style classes were introduced, my guess is that it's mainly because what you *usually* want when defining a function in a class is for that function to be an instance method. That is, the following code:: class C(object): def foo(self): pass c = C() c.foo() should be much more common than:: class C(object): def foo(): pass C.foo() because the whole point of creating a class is to allow you to create instances. But if ``C.foo`` and ``c.foo`` are just regular functions, then how will ``c.foo()`` get the ``self`` argument? Certainly a normal ``foo()`` shouldn't be inserting a magical ``self`` argument. So *some* indirection has to happen when a function is used in a class. Python's solution to this problem is to introduce descriptors, which are the "something" that classes have to do. All classes invoke __get__ whenever any of their attributes are accessed. With a normal function object, invoking __get__ turns it into an instance method: >>> class C(object): ... pass ... >>> def foo(self): ... pass ... >>> foo <function foo at 0x00E69530> >>> foo.__get__(C(), C) <bound method C.foo of <__main__.C object at 0x00E738F0>> >>> class C(object): ... def foo(self): ... pass ... >>> C().foo <bound method C.foo of <__main__.C object at 0x00E59C50>> As a result, if you want to have a callable as a class attribute and you don't want that callable to give you an instance method when you access it, you can't use a regular Python function. Personally, I think that's pretty reasonable since 99% of the time, I *do* want an instance method[1]. STeVe [1] The other 1% of the time, I pretty much always want a classmethod. I'm still convinced that staticmethods are basically silly when I can just declare a module level function. ;) -- http://mail.python.org/mailman/listinfo/python-list