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. -- http://mail.python.org/mailman/listinfo/python-list