Only one convention to make explicit the instance of the object within the class.
Python is a language that was initially created with the functional paradigm. Over time, support has been placed for object-oriented code, which is another paradigm. At the time the authors decided that it should be explicit the passage of the object to which belongs the function that is being called when the function belongs to a class because the focus of the language were the functions. So they agreed it would be the first parameter and the name would be self
.
I'm going to create a fictional story of what the Python authors think would be, but it's just a joke to illustrate and try to give an understanding that makes more sense than just a convention.
Suppose I want to write several common functions for a certain object, which in the case of Python can be a simple dictionary.
That way, when calling each function I wrote, I would have to pass that object to that function and then the parameters themselves of the function. 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 that I mount a series of functions that work on the same type of object. We can say that I created a class of functions. For organization effect we will agree that the function name becomes NomeDaClasse.NomeDaFunção(Objeto, Param1, Param2, ...)
.
I would have something like this:
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, just 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, 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 very similar way to the OO class structure, then I could figure out how to pass the attributes of my object to an initializer, which I I will also agree with a very different name, for example, __init__
and through it I pass the values of the attributes of my "object" and create a single instance of that class. Everything will look very much like the OO classes and objects.
I'll also agree that I can call the functions of my object with a simpler syntax, for example:
MeuObjeto.MinhaFuncao(Param1, Param2, ...)
As I have simplified everything but I do not want the programmer to know that there are things implicit in these conventions, I will keep in the signature of the functions within the class a special name, which I will 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 easier for the programmer to use a syntax that looks very similar to the OO syntax and how my language is functional, I'll make it explicit to those conventions I've made, leaving the name self
within the signature of functions within the class.