First of all, there is no getters
or setters
Java style in Python . There is no way, they do not exist. You can do something similar, yes, no doubt, but what we do will never have the philosophy of Java . There is a concept that describes well the differences in this sense between both languages, you can find it mentioned in many places, and it is the idea of the "Malicious Programmer", in Java there is a very strong encapsulation in the objects , certain properties can be accessed only through the appropriate methods, the idea is that in Java you take care of the objects of this hypothetical Bad Programmer, in Python that idea is replaced by a: "we are all adults ", that is, everyone knows what they are doing, if you want to modify an internal attribute of an object, perfect, you are supposed to know what you are doing. Please do not misinterpret this, it is simply a metaphor to describe the differences in this question and between both languages, no thing is better than the other, they are different conceptions. All this to re-emphasize "there is no getters
or setters
Java style in Python ", no matter how hard we put it, always but always we will have some way to access the internal attributes of an object. Having said that, let's go to your particular question:
I'm going to rewrite your code to simplify it, we define the class ResponseUpdateDTO
, to have two attributes serial
that in principle could be a string, and archivos
, which will be a list.
class ResponseUpdateDTO(object):
def __init__(self):
self._serial = ""
self._archivos = []
def set_serial(self, serial):
self._serial = serial
def get_serial(self):
return self._serial
def get_archivos(self):
return self._archivos
def set_archivos(self, archivos):
self._archivos = archivos
Some comments:
- It is convenient most of the time to define the method
__init__
, it is not a constructor, it is simply one of the first methods that is executed when an object is instantiated and by convention it is usual to initialize here all the attributes of the object, also eventually, parameters are defined in which parameters are passed in the initialization.
- Another convention that you have used very well is to name attributes and methods with the script under
_
in front, with this we say to any other programmer: "look, these data and these functions do not use them please", in fact they are automatically removed from the documentation that you could obtain using help()
, but it does not mean that they can not be used.
- As you can see also, the pseudo
getter
and setter
for the files does not differ from the others that you have defined.
Clearly as the code is now, you could do:
r = ResponseUpdateDTO()
r.set_archivos(['archivo1', 'archivo2'])
print(r.get_archivos())
But you can also do this:
r._archivos = ['archivo1', 'archivo2']
Clearly there is no encapsulation, you are directly accessing the attribute _archivos
that we imagine private, in fact if your setter
has some validation logic, it would not be running.
Originally you tried to use "decorators" to get closer to the functionality you expect to see and you are indeed on the right track. Let's see how to use them and what we can really achieve:
class ResponseUpdateDTO(object):
def __init__(self):
self._serial = ""
self._archivos = []
@property
def serial(self):
return self._serial
@serial.setter
def serial(self,serial):
self._serial = serial
@property
def archivos(self):
return self._archivos
@archivos.setter
def archivos(self, archivos):
self._archivos = archivos
r = ResponseUpdateDTO()
r.archivos = ['archivo1', 'archivo2']
print(r.archivos)
What have we achieved with this?
- First, the
archivos
method will behave like getter or
setter depending on how we use it
- We can incorporate logic, in particular the setter, for example to validate the data entered.
But, as I said at the beginning, there is always the possibility of doing this:
r._archivos = ['archivo1', 'archivo2']
print(r._archivos)
But since the concept in Python is that we are all adults it should not be too big a problem, even so, there is a way to prevent doing the above, which is to name all the private variables with the double hyphen under __
, for example:
@archivos.setter
def archivos(self, archivos):
self.__archivos = archivos
In this way, by doing this:
r._archivos = ['archivo1', 'archivo2']
You will get a beautiful Exception:
Traceback (most recent call last): File "python", line 29, in
AttributeError: 'ResponseUpdateDTO' object has not attribute
'__files'
This is nothing more than a trick, what the interpreter does in these cases, is to "rename" the variable internally as _classname__archivos
, so that you could also eventually do
r._ResponseUpdateDTO__archivos = ['archivo1', 'archivo2']