Let’s go in pieces:
When "the whole Internet" says one thing and you don’t want to do the same - who do you think is going the other way?
In Python there is no custom of using getters and setters, because you have to think differently. When you speak of "private attributes" - they are private to "who"?
The idea of OO encapsulation is that people using their class and pubic methods do not need to worry with the private states, nor should they try to touch them directly. This makes it easy that when developing the class you don’t have to worry about "and if someone leaves this attribute inconsistent" between two method calls, and for those who are using it you don’t have to worry about "if I change this value, I break something in the functioning of the object"?
The purpose of private attributes is NOT to, for example, prevent someone who uses your class from reading some value that you consider private for security reasons to protect themselves from something like a "malicious programmer" who is making use of your class.
Since languages such as Java and C++ are defined, it gives the impression that private attributes and methods can provide security against a malicious programmer who is using his class. This security is not real - in both languages it is possible to access these private attributes - sometimes going around a lot.
In Python and other dynamic languages, the use of introspection makes it easy to find and use any attribute marked as private (even those prefixed with __
)
In short: if someone is writing code that will run in the same process as their class with private attributes - they can and should be able to access the data. It is different from the case of a programmer on a different system than yours who will access your data by an API. In this case, private attributes are simply not exposed in the API. In Python, instead of trying to force inaccessible private attributes, it is customary to say that the language is used by "consenting adults" .
So the practice is to prefix private attributes and methods with a single _
: so whomever use the class knows not to mess with these attributes.
Now, Python has a mechanism much powerful for attribute access, which we call "Descriptor Protocol" - this is what is used internally by property
to create methods - it goes far beyond what Property allows (basically you can define attributes in a class that automatically has getters and custom setters - just create a special class for these attributes with the methods __get__
, __set__
or __del__
- the Property does this).
That said, Property is a facilitator for you, when you want to read or write an attribute, execute some custom code that can transform or validate the data of that attribute, when it is accessed (for example, read the value of a database, make a formatting, validate the type of attribute, etc...).
Using Property (or getters and setters) to simply store the value as it came and return it as it came, makes no sense - unless, for example, you want the class to be thread-safe and use that code to use Locks and semaphores in changing the attributes. And it’s by "not making sense" that the Internet recommends not to do - simply because your program will be exactly the even with or without getters and setters -
Without the Property:
class Teste:
def __init__(self, valor):
self.valor = valor
With the Property:
class Teste:
def __init__(self, nome):
self.nome = nome
@property
def nome(self):
# Este código é executado quando alguém for
# ler o valor de self.nome
return self._nome
@nome.setter
def nome(self, value):
# este código é executado sempre que alguém fizer
# self.nome = value
self._nome = value
And that’s it - who’s going to use your code, is not going to use a "Setter" call - the magic of Python is that if you need to put custom logic on the getter and Setter, that’s completely transparent to whom uses its class and its attributes. If no extra logic is required for a given attribute, there is no reason to create a Property for it.
"...thread-safe and use this code to use Locks and semaphores in changing attributes." , very good example of a very useful thing that can be achieved in this way
– Miguel
Now it became much clearer, as it is more accessible in youtube videos Object Orientation classes in other languages, as Java for example, during learning I ended up with some addictions and I like the programming style of Python much more than java, so whenever I come across situations where in java would be done in a certain way and the Python community says to avoid before joining I want to understand why to avoid (not belittling the community of course, for sure are much more experienced than me, it is just a matter of learning). Thank you so much for your help.
– Afonso Medeiros
There is a legal article about this and other customs for those who come from static languages. It is old, but it has always been a "classic" - ó "Python n~ao é Java": http://dirtsimple.org/2004/12/python-is-not-java.html
– jsbueno