Why does Python make itself explicit?

Why does Python need an explicit self parameter in every argument list?

For example, in the Complex class specified in the documentation

 class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpart def conjugate(self): self.i = -self.i x = Complex(3.0, -4.5) # 2 instead of 3? x.conjugate() # No parameters? 

I initially found that it was deeply confusing that __init__( ) seems to require 3 arguments, but you call Complex( ) with only 2.

What is the reason that the self parameter is explicit and implicit?

+4
source share
4 answers

Here is a good GvR article on this subject. It talks about why the explicit self reference will remain here.

Points that he raises among others:

enhances equivalence

 foo.meth(arg) == C.meth(foo, arg) 

The ability to dynamically attach methods to a class, which can then be used from all new and existing objects of this class:

 def meth(myself, arg): myself.val = arg return myself.val # Poke the method into the class: C.meth = meth 

I recommend that you read the rest of the article. This is pretty interesting.

+5
source

Regarding the argument "self": it identifies an instance of a particular class. In C ++, for example, the same thing is done, but under the hood.

Further reading: http://linuxgazette.net/issue56/orr.html

+1
source

That's how it is. Python objects are actually bags of properties (attributes). Some of them are regular values, while others are functions. They have no special binding to the class, except for the attribute of its instances. The method invocation syntax is just a little sugar, taking care of passing the first parameter to you. Actually, methods are just simple functions, and you can name them as such by explicitly passing the first parameter.

I do not know why this choice was made, but I believe that this is due to the fact that you can assign free functions as attributes to existing objects, and then call them methods; without an explicit self parameter, this will lead to even more confusion.

The mechanism is similar to Javascript, only in Javascript the this argument is implicitly passed as a local variable named this without an explicit parameter, whereas in Python you can choose the name your own sympathy through the explicit first parameter - self not a keyword, but just a convention. This difference also means that you can use functions as methods more easily - the javascript function that uses this will break if used outside the context of the object (more precisely, in the context of the default object, usually window ), but in Python, you can pass matching object as the first parameter.

Note that other OOP differences (Java, C ++, etc.) also pass the self / this parameter to your method, but they do it implicitly, and this does not appear as an explicit argument. These languages ​​do not allow methods to be called as free functions, although (and vv., You cannot use a free function as a method).

What this is called __init__ : there is at least one advantage, namely that you can rename a class without renaming the constructor. This makes refactoring easier and less error prone. BTW, Python is not alone in this - PHP uses __construct , although constructors with a class name are also supported, but no longer recommended.

+1
source

(The following is a slight simplification, but should give you an idea of ​​how Python object creation is created.)

Statement

 x = Complex(3.0, -4.5) 

does not call Complex.__init__ directly. Rather, it is somewhat identical to the following:

 x = Complex.__new__(Complex, 3.0, -4.5) Complex.__init__(x, 3.0, -4.5) 

You can still think this is uselessly confusing. But it is designed to provide maximum flexibility. You can override __new__ (which is usually just inherited from the base class) to do something more (or different) than return an instance of the class. However, most of the time you do not need, so that you do not have to make two calls all the time just to create and initialize the object, it ends up reducing the processing of the type itself as the called object to create and initialize the object in one step.

0
source

All Articles