function v. method
Duncan Booth
duncan.booth at invalid.invalid
Tue Jul 18 03:42:20 EDT 2006
danielx wrote:
>>>> Foo.func = dan # <-- Appearantly, something magical happens here,
because...
>>>> Foo.func
><unbound method Foo.dan>
>>>> f = Foo.func
>>>> f is dan # <-- things begins to look suprising here.
> False
>>>> ismethod(f)
> True
>
> Imagine my surprise. Why would Python do this?
>
Nothing magical happens at the point you said. The assignment is just an
assignment and you saw that the function was stored unchanged when you
looked in the class's dictionary.
The magic happens when you access a member of a class or an instance. If
the value is a descriptor then its __get__ method is called. Roughly
speaking, Foo.func is equivalent to:
>>> Foo.__dict__['func'].__get__(None, Foo)
<unbound method Foo.dan>
Python does this so that it can support other descriptor types such as
property, classmethod, staticmethod.
You can see this happening if you define your own descriptor:
>>> class MyDesc(object):
def __get__(self, *args):
print "__get__ called", args
return None
>>> d = MyDesc()
>>> Foo.oops = d
>>> Foo.oops
__get__ called (None, <class __main__.Foo at 0x00B3F930>)
http://docs.python.org/ref/descriptor-invocation.html has a description of
this. Although it claims "Note that descriptors are only invoked for new
style objects or classes (ones that subclass object() or type())." the
descriptor mechanism is partially implemented for old style classes.
Several aspects of descriptors don't work properly though in old-style
classes which is one reason why you should always use new-style classes.
> Privates don't have to be entirely absent from Klass.__dict__
> (which would make Python not introspective); they can just be invisible
> when using the dot-syntax.
You could implement that using a data descriptor, but if you are going to
prevent access to your private variables using the dot operator, then your
code is going to look pretty silly with a lot of references to
self.__dict__['theprivate'] which doesn't gain anything in readability over
self.__theprivate.
More information about the Python-list
mailing list