Then - both forms work - what is done in the first example is that, even if it is a class method call, the parameter is passed explicitly - that is - the "printa" function could be a normal function of Python, and not a method of the same class, which would play the same role.
In the second form, the value of "text" is annotated as an attribute of the object - and the method is called without any explicit parameters - it uses the "text" attribute of the object.
In practice, the first approach is typical of a structured application drawing. Even using the class, and objects, the "type of reasoning" that is used when the parameters are explicitly passed is the structured one.
In contrast, grouping data and functions that will work with these data (methods) on the same object, is the very foundation of Object Oriented thinking. One of the great gains of an object-oriented programming is that you do not have to pass all the parameters that represent the state of that object as parameters to the methods: 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 character in a game, for example, has to have as parameters the coordinates on the map, a reference to the map object itself, how much energy, speed, if it is in the possession of some (and which ones), and to be effectively drawn on the screen, you still have to have reference to 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 on 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 that structure as a parameter to all the functions that will deal with the character, is happening contrary to what happens in your first example: using a structured programming in form, but in practice it is object oriented.
That's the conceptual part. Speaking in more technical and Python-specific details - in its first example, the value of "text" is accessible with 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. Take a test, and have self.__dict__["text"]
printed. 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 function outside of the object, nor other methods of the object, can access the value of self
.