How User-defined method objects are created?
Duncan Booth
duncan.booth at invalid.invalid
Sat Mar 20 12:24:37 EDT 2010
Joaquin Abian <gatoygata2 at gmail.com> wrote:
> "User-defined method objects may be created when getting an attribute
> of a class (perhaps via an instance of that class), if that attribute
> is a user-defined function object, an unbound user-defined method
> object, or a class method object. When the attribute is a user-defined
> method object, a new method object is only created if the class from
> which it is being retrieved is the same as, or a derived class of, the
> class stored in the original method object; otherwise, the original
> method object is used as it is."
>
> It is a bit of a tongue-twister for me. What the last sentence means?
> Please, I beg for a simple example of the different objects (user
> defined function, user defined method, class method) refered.
>>> class A(object):
def foo(self): pass
>>> class B(object):
def bar(self): pass
>>> B.baz = B.bar
>>> B.foo = A.foo
>>> instance = B()
>>> B.foo
<unbound method A.foo>
>>> B.bar
<unbound method B.bar>
>>> B.baz
<unbound method B.bar>
>>> instance.foo
<unbound method A.foo>
>>> instance.bar
<bound method B.bar of <__main__.B object at 0x00000000036B7780>>
>>> instance.baz
<bound method B.bar of <__main__.B object at 0x00000000036B7780>>
>>> B.__dict__['bar']
<function bar at 0x00000000036C5048>
>>> B.__dict__['baz']
<unbound method B.bar>
>>> B.__dict__['foo']
<unbound method A.foo>
So, we have a function 'bar' stored in B's dict. When you access the
function as the attribute B.bar Python 2.x will create an unbound method
object. When you access the function through instance.bar Python creates a
bound method. Note that every time you access instance.bar it creates
another new method object:
>>> instance.bar is instance.bar
False
B.baz is an unbound method stored directly in B's dict. When you access
instance.baz you get a new bound method object (it's at the same memory
location as the previous one but that's only because the lifetimes don't
overlap). Somewhat suprisingly the same also happens if you access B.baz:
it creates a new unbound method from the existing unbound method:
>>> B.bar is B.__dict__['bar']
False
B.foo is an unbound method stored directly in B's dict, but it is a method
of an A and B doesn't subclass A, so when you try to access B.foo you just
get the stored unbound method it isn't converted into a new object.
More information about the Python-list
mailing list