In Python, is there any rule or advantage to using 'Self'?

Question:

Let's consider the examples below:

Example 1:

> class PrintText():
>     def __init__(self):
>         text = 'Funciona!'
>         self.printa(text)
>         
>     def printa(self, text):
>         print(text)

Example 2:

> class PrintText():
>     def __init__(self):
>         self.text = 'Funciona!'
>         self.printa()
>         
>     def printa(self):
>         print(self.text)

Let's suppose that in the PrintText class there are several cases like this, where a certain variable is used by only one or two functions; Is it better to use Example 1 which passes the variable as an argument to the function, or use Example 2 which explicitly declares 'self'? Both examples work, but is there an advantage between them, or is one of them incorrect?

Answer:

So – both ways work – what's done in the first example is that even when it comes to calling a class method, the parameter is passed explicitly – ie – the "printa" function could be a normal Python function, and not a method of the same class, which would fulfill the same role.

In the second way, the value of "text" is annotated as an attribute of the object – and the method is called without any explicit parameters – it uses the attribute of "text" of the object.

In practice, the first approach is typical of a structured application design. Even using the class, and objects, the "type of reasoning" that is used when parameters are passed explicitly is the structured one.

In contrast, grouping data and functions that will work with that data (the methods) in the same object is the very foundation of "Object Oriented" thinking. One of the great gains of object-oriented programming is precisely not having to pass all the parameters that represent the state of that object as parameters to the methods: the methods have access to these values ​​in the form of attributes.

In your example you are using a single attribute. But a complex object could have dozens of different attributes – a game character, for example, has to have as parameters the coordinates on the map, a reference to the map object itself, how much energy it has, speed, if it has any item (and which ones), and, to be effectively drawn on the screen, it still has to reference the images themselves that will be used to draw it, position on the screen, and so on – using the structured approach, these dozens of parameters would have to be passed in multiple function calls to handle the same object.

Note that if someone is using a data structure that groups the parameters related to an item – this game character, for example, and passes this structure as a parameter to all the functions that will deal with the character, the opposite is happening. it happens in its first example: using programming structured in form, but in practice it is object-oriented.

That's the conceptual part. Speaking of more technical, Python-specific details – in your first example, the value of "text" is accessible by that name in the __init__ method as a local variable, and again as a local variable in the printa function. In the second example, the local variable that is used in both methods is self – the text value is stored in an "object variable" – that is, inside the __dict__ dictionary of the self object. Do a test, and have it print self.__dict__["text"] . In this way it is visible and accessible to anyone who has access to the object – in the concept of OO, it is a "public" attribute. In the first form, no functions from outside the object, nor other methods of the object, can access the value of self .

Scroll to Top