[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

How User-defined method objects are created?

Joaquin Abian

3/20/2010 1:55:00 PM

I'm trying to understand the description of method object creation in
the python 2.6 language reference (3.2. The standard type hierarchy)
with little success. The points knocking me are:

"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.
Are maybe the refered objects exemplified by :

#python 3.1
class Klass():

def met(self):
print('method')

def func():
print('function')

@classmethod
def kmet(klass):
print('classmethod')

or it is talking about another thing?
What is the difference with python 3 where there is no mention to the
unbound user-defined method object (same section in python 3 language
reference):

"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 or a class method object."

I'm trying to learn, however the task is revealing as an enormous
undertaking :-)

JA


4 Answers

Duncan Booth

3/20/2010 4:25:00 PM

0

Joaquin Abian <gatoygata2@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.

Terry Reedy

3/20/2010 4:40:00 PM

0

On 3/20/2010 9:54 AM, Joaquin Abian wrote:
> I'm trying to understand the description of method object creation in
> the python 2.6 language reference (3.2. The standard type hierarchy)
> with little success. The points knocking me are:
>
> "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.
> Are maybe the refered objects exemplified by :
>
> #python 3.1
> class Klass():
>
> def met(self):
> print('method')
>
> def func():
> print('function')
>
> @classmethod
> def kmet(klass):
> print('classmethod')
>
> or it is talking about another thing?
> What is the difference with python 3 where there is no mention to the
> unbound user-defined method object (same section in python 3 language
> reference):

Python3 does not have unbound method objects. Klass.met above is just a
function.l

> "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 or a class method object."
>
> I'm trying to learn, however the task is revealing as an enormous
> undertaking :-)

One can successfully use the language in the normal way without
understanding every detail of every oddball corner case. Recent 2.x is
complicated by duplication (two user object systems) and
back-compatibility constraints. Most new users do not need to bother
with obsolete complications.

Terry Jan Reedy

Joaquin Abian

3/20/2010 9:33:00 PM

0

On Mar 20, 5:39 pm, Terry Reedy <tjre...@udel.edu> wrote:
> On 3/20/2010 9:54 AM, Joaquin Abian wrote:
>
>
>
> > I'm trying to understand the description of method object creation in
> > the python 2.6 language reference (3.2. The standard type hierarchy)
> > with little success. The points knocking me are:
>
> > "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.
> > Are maybe the refered objects exemplified by :
>
> > #python 3.1
> > class Klass():
>
> >    def met(self):
> >            print('method')
>
> >         def func():
> >            print('function')
>
> >         @classmethod
> >    def kmet(klass):
> >            print('classmethod')
>
> > or it is talking about another thing?
> > What is the difference with python 3 where there is no mention to the
> > unbound user-defined method object (same section in python 3 language
> > reference):
>
> Python3 does not have unbound method objects. Klass.met above is just a
> function.l
>
> > "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 or a class method object."
>
> > I'm trying to learn, however the task is revealing as an enormous
> > undertaking :-)
>
> One can successfully use the language in the normal way without
> understanding every detail of every oddball corner case. Recent 2.x is
> complicated by duplication (two user object systems) and
> back-compatibility constraints. Most new users do not need to bother
> with obsolete complications.
>
> Terry Jan Reedy

Terry, Right, I was just reading about this difference in 2 vs 3 in
Lutz's book.
Well, in fact in my case I'm not a newcomer to python (neither a
professional). I have been programming for more than 4 years in python
mainly medium size scientific data management applications. Currently
I can write at a moderate speed and Im familiar with properties,
decorators, etc.

That's why it is so frustrating went I get lost in the language
reference manual in a matter I wrongly though was a simple stuff.

Thanks for your helpful comments.

JA

Joaquin Abian

3/20/2010 9:42:00 PM

0

On Mar 20, 5:24 pm, Duncan Booth <duncan.bo...@invalid.invalid> wrote:
> Joaquin Abian <gatoyga...@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.

Thanks Duncan, I think I got the idea. Your explanation together with
the comment from Terry about the absence of unbound method objects in
python 3 cleared some dust from my neuron(s)
Thanks!
JA