How User-defined method objects are created?

Duncan Booth duncan.booth at invalid.invalid
Sat Mar 20 17:24:37 CET 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