If someone recommends you use properties
in python, you almost certainly do not know how python works or you think it is programmed the same as in java. The pythonic style is to be "explicit" rather than "implicit", and the properties go against the pythonic style of doing things.
All the magic of the python inheritance mechanism is largely due to the operation of the descriptors . All methods that have a class, both explicit and implicit , are descriptors and their operation is carefully optimized so that it does not overload the execution of the code. This is how python manages multiple inheritance, static and class methods, metaclasses and class decorators. Get the injection of dependencies simple ( mixins ) or dynamic programming, for example. However, although the descriptors are omnipresent, they are totally transparent to the user and he does not know that he is using them.
We can define a descriptor as an object that has at least one of these methods:
-
__get__
for reading
-
__set__
for modification
-
__delete__
for deletion
These methods conform what is called descriptor protocol and will determine the treatment that the python interpreter will make of this object.
We have two types of descriptors:
-
Non-data descriptor ( "Non-data descriptor" ): these are the ones with only the
__get__
method defined
-
Data descriptor ( "Data descriptor" ): when at least one of the other methods is defined,
__set__
and / or __delete__
.
If you have looked at the documentation of property
it will sound a lot, since a property is built by defining these three functions. In short, a property
is a descriptor that implements the three methods and, optionally, defines an attribute for the documentation. Therefore, a property is a data descriptor .
If you are interested in the topic, some time ago I wrote some descriptor articles: link
> But let's go to the question: Why the deleter
?
The first decorator, @property
, implements the __get__
method of the descriptor. If we do not do anything else, we would have a read-only property. The other descriptor methods ( __get__
/ __delete__
) will give an error if they are invoked.
The decorator setter
copies the property to replace the __set__
method with the one obtained from the decorator. In this way, the property can be modified.
The last decorator deleter
would serve to implement the method __delete__
of the descriptor. When this method is invoked, it is the last opportunity to release resources before the instance property disappears.
Keep in mind that, while an attribute is defined for each instance of the class, the "property" is common for all instances. When the deleter
is invoked, it is not to release all the resources that the property uses, but only those that are specific to the instance. And, of course, it also does not serve to eliminate the property, it is not a "destructor" in the way that is understood in other object-oriented languages.