[Tutor] Don't understand this class/constructor call syntax

Steven D'Aprano steve at pearwood.info
Wed Jul 27 01:18:00 CEST 2011


dave wrote:
> Is it even possible to replace the implicit self argument of the initializer
> by passing something else?  If so, what would be the syntax.

Yes, by calling an "unbound method".


Consider this class:


class MyClass:
     def func(self, x):
         return x+1


When you run this code, Python creates a class object MyClass, 
containing one method object, "func". Notice that the syntax for 
defining a method is the same as defining a function, except that it is 
inside a class. In fact they are the same things, except that methods 
are a lightweight wrapper around the real function object. We can see 
this by inspecting the method:

 >>> instance = MyClass()
 >>> instance.func
<bound method MyClass.func of <__main__.MyClass instance at 0xb7f6a08c>>


The method wrapper is responsible for automatically providing the "self" 
argument when you call the function on the instance. The terminology is 
that the method is "bound" to the instance, so the wrapper knows what to 
give as self. When you call the method instance.func(42), the wrapper 
calls the underlying function func(instance, 42).

(Aside: Python also provides two other kinds of methods, classmethod and 
staticmethod, which do something different. And of course the machinery 
that makes this work is available for you to write your own custom 
method types, if you can think of a need.)


But you can also access the method directly from the class object:


 >>> MyClass.func
<unbound method MyClass.func>


In this case, the method wrapper doesn't have access to an instance to 
use as "self" -- it is "unbound".

(Note for Python 3, it was determined that there is no need to provide 
unbound methods anymore, and the underlying function object is returned 
instead.)

Before you can actually call the function, you need to provide an 
argument for "self". You can do that by hand:

 >>> MyClass.func(instance, 42)
43


In Python 2, the unbound method wrapper enforces that the first argument 
is actually an instance of MyClass. But in Python 3 unbound methods are 
gone, and so you can pass anything you like.



-- 
Steven


More information about the Tutor mailing list