Let's break it down:
When "the whole internet" says one thing and you do not want to do the same thing - who do you think is going against it?
In Python there is no custom to use getters and setters, because you have to think differently. When you speak of "private attributes" - are they private to "who"?
The idea of encapsulation in OO is that people using their class and pubic methods do not need to worry about private states, nor should they try to manipulate them directly. This makes it easy for you when you develop the class you do not have to worry about "what if someone leaves this attribute inconsistent" between two method calls, and whoever is using it does not have to worry about "if I change that value, something in the functioning of the object "?
The purpose of private attributes is NOT to prevent someone using your class from reading some value that you consider private for security reasons to protect yourself from something like a "malicious programmer" making use of your class.
Because 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 your class. This security is not real - in both languages it is possible to access these private attributes - sometimes taking many turns.
In Python and other dynamic languages, the use of introspection makes it very 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 your class with private attributes - it can and should be able to access the data. It is different from the case of a programmer on a system other than yours that 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 unreachable private attributes, it is customary to say that language is used by "consenting adults."
So, the practice is to prefix private attributes and methods with a single _
: so whoever uses the class knows that it does not have to tinker with those attributes.
Now, Python has a very powerful mechanism for attribute access, which we call the "descriptor protocol" - this is what is used internally by
property
to allow you to create methods - it goes a long way in addition to what proeprt allows (basically you can define attributes in a class that automatically have custom getters and setters - just create a special class for these attributes with the methods
__get__
,
__set__
or
__del__
- the property does this) .
That said, the property is a facilitator for you, when you want to read or write an attribute, run 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 format, validate the attribute type, etc ...).
Using the property (or getters and setters) to simply save the value as it came and return it as it came, does not make sense - unless, for example, you want the class to be thread safe and use this code to use locks and semaphores in changing the attributes. And it is by "making no sense" that the internet recommends not to do it - simply because your program will be exactly 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 then - who will use your code, will not use a chaos to the "setter" - the magic of Python is that if you need to put custom logic in the getter and setter, this is completely transparent to anyone who uses your class and its attributes. If no extra logic is required for a given attribute, you do not have to create a property for it.