467,207 Members | 1,308 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,207 developers. It's quick & easy.

why descriptors? (WAS: Make staticmethod objects callable?)

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. ;)
Mar 1 '06 #1
  • viewed: 1091
Share:

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Denis S. Otkidach | last post: by
4 posts views Thread by Michal Vitecek | last post: by
68 posts views Thread by Marco Bubke | last post: by
reply views Thread by Robin Becker | last post: by
11 posts views Thread by cjl | last post: by
10 posts views Thread by Nicolas Fleury | last post: by
12 posts views Thread by bruno at modulix | last post: by
3 posts views Thread by redefined.horizons@gmail.com | last post: by
8 posts views Thread by M.Endraszka@gmail.com | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.