Questions on Instance methods

dieter dieter at handshake.de
Sat Apr 20 01:29:55 EDT 2019


Arup Rakshit <ar at zeit.io> writes:

>>    When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method.
>
> Here I have 2 questions:
>
> 1. How do you create an instance method object from a class method object by using either the class or the instance?

Typically, it happens automatically by accessing "instance.method".
The "types" module contains a type which allows you to
create instance methods manually. However, in this case,
you decide what becomes its "__self__" and its "__function__".

> 2. Why in both cases the __self__ is set to Class only?

Because of the "class method".

The "*method" objects have the task to provide the (implicit) first
argument to the function. For a function defined as "classmethod",
this is the class (otherwise the instance).

> 3. Would you give me examples also while explaining this?

python3
>>> class C:
...   @classmethod
...   def cm(cls): print(cls)
...   def im(self): print(self)
... 
>>> C.cm
<bound method C.cm of <class '__main__.C'>>
>>> c=C()
>>> c.cm
<bound method C.cm of <class '__main__.C'>>
>>> c.im
<bound method C.im of <__main__.C object at 0xb785258c>>
>>> C.cm.__self__
<class '__main__.C'>
>>> c.cm.__self__
<class '__main__.C'>
>>> c.im.__self__
<__main__.C object at 0xb785258c>

>>   When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.

I agree that the above paragraph could be improved.

It addresses the case "cm" above: you access a method
defined as a class method (the "is derived from a class method object" above
means "is created for the access to a class method").
The paragraph wants to stress that even though the (bound method) attribute
is named "__self__", it actually contains the class and not a
(class) instance.


> Here x is an instance of C. Would you give me an example to illustrate why " x.f(1) or C.f(1) is equivalent to calling f(C,1)” ?

Remember that the purpose of the "*method" objects it to automatically
provide the first argument ("cls" or "self") to the function.

Because accessing a method automatically creates a method
object, it is non trivial to access the "underlying function".
One possibility is to use "__func__" on the method object.
With this in mind we get for the above example:

>>> c.cm.__func__(C)
<class '__main__.C'>
>>> c.cm()
<class '__main__.C'>
>>> C.cm.__func__(C)
<class '__main__.C'>
>>> C.cm()
<class '__main__.C'>



More information about the Python-list mailing list