python – Why do we have to use the self attribute as an argument in methods?

Question:

I watched a video class where it is said that every method is required to pass the self parameter in the method definition, as in the example below:

class Complex(object):
    def __init__(self, real, imag):
        self._real = real
        self._imag = imag

This example I took from here . The only explanation I found on this page was this. But I didn't understand what the author meant.

The method's first argument is always referenced at the beginning of the process. By convention, the method's first argument is always named self. Therefore, self attributes are instance attributes of the class.

In Java, which is a language I am already familiar with, there is no such need. Does anyone know why this obligation in Python?

Answer:

Just a convention to make the object instance within the class explicit.

The language author defines (in question 4.21) self as follows:

Self is merely a conventional name for the first argument of a method — ie a function defined inside a class definition. A method defined as meth(self, a, b, c) should be called as x.meth(a, b, c) for some instance x of the class in which the definition occurs; the called method will think it is called as meth(x, a, b, c).

I'm going to create a fictional story that is just a joke to illustrate and try to give an understanding that makes more sense than just a convention as explained by the author.

Suppose I want to write several common functions for a certain object, which in Python's case might be a simple dictionary.
That way, when calling each function I've written, I'd have to pass that object to that function and then the parameters of the function itself. Example:

item = {'qt': 10, 'nome': 'Banana', 'preco': 12.20}

def Desconto(objeto, percentual):
  objeto['preco'] = objeto['preco'] * (percentual / 100.0)

And to call the function:

Desconto(item, 10)

Let's say I assemble a series of functions that work on top of the same type of object. We can say that I created a function class . For organization purposes, let's agree that the name of the functions NomeDaClasse.NomeDaFunção(Objeto, Param1, Param2, ...) . I would have something like:

def MinhaClasse.Funcao1(Objeto, Param1, Param2, ...)
   ...
def MinhaClasse.Funcao2(Objeto, Param1, Param2, ...)
   ...
def MinhaClasse.Funcao3(Objeto, Param1, Param2, ...)
   ...

Now whenever I want to call a function I just need to identify the class and know that the first parameter is always an object of a certain type that that class of functions understands.

If I agree that in my source code I can write this set of functions in a different way, for example, so as not to repeat the class name in the function name, I'll put it like this:

class NomeDaClasse ()
   def Funcao1(Objeto, Param1, Param2, ...)
     ...
   def Funcao2(Objeto, Param1, Param2, ...)
     ...

When I want to call the function of this class, I would continue to do:

NomeDaClasse.NomeDaFuncao(Objeto, Param1, Param2, ...)

But since I created a way very similar to the OO class structure, so I could find a way to pass my object's attributes into an initializer, which I'll also agree with a very different name, by example, __init__ and through it I pass the attribute values ​​of my "object" and create a single instance of this class. Everything will look very similar to the OO classes and objects.

I'll also agree that I can call my object's functions with a simpler syntax, for example:

MeuObjeto.MinhaFuncao(Param1, Param2, ...)

As I've simplified everything but I don't want the programmer to know that there are things implicit in my conventions, I'll keep a special name in the functions' signature inside the class, which I'll call self to indicate the parameter that is the object of my class. When making the call, internally my compiler would do the following:

MeuObjeto.MinhaFuncao(...) => MinhaClasse.MinhaFuncao(MeuObjeto, ...)

So I made it easy for the programmer who can use a syntax very similar to the OO syntax and I'll make it explicit for these conventions I made, leaving the name self inside the signature of the class's methods.

Scroll to Top