In languages that rely on getters and setters such as Java, they are not supposed to and did not expect anything other than what they say - it would be surprising if x.getB() did nothing except return the current logical value attribute b , or if x.setB(2) did anything other than a small amount of internal work to make x.getB() return 2 .
However, there are no language guarantees regarding this expected behavior, i.e. restrictions associated with the compiler, with the body of methods whose names begin with get or set : rather, it left to common sense, social convention, "style guides" and testing.
The behavior of xb access and assignments, such as xb = 2 , in languages that have properties (a set of languages, including but not limited to Python), is exactly the same as for getter and setter methods in, for example, Java: the same expectations, the same disadvantages of warranties guaranteed by languages.
The first gain for properties is syntax and readability. To write, for example,
x.setB(x.getB() + 1)
instead of the obvious
xb += 1
screaming for revenge on the gods. In languages that support properties, there is absolutely no reason to force class users to go through such Byzantine patterns, affecting their readability of the code without any problems.
In Python, in particular, there is another great potential for using properties (or other descriptors) instead of getters and setters: if and when you reorganize your class so that the base setter and receiver are no longer needed, you can (without if you break the class, published API), simply eliminate those methods and the property that uses them, making b normal "stored" attribute of class x , and not the "logical" obtained and set computationally.
In Python, executing directly (when possible), and not through methods, is an important optimization, and the systematic use of properties allows you to perform this optimization whenever possible (always exposing the "normal stored attributes" directly, and only those that really need computation when access and / or configuration using methods and properties).
So, if you use getters and setters instead of properties, without affecting the readability of your users' code, you also spend machine cycles for free (and the energy that comes to their computer during these cycles ;-), again without a good reason.
Your only argument against the properties is, for example, that "the external user will not expect any side effects as a result of the assignment, as a rule"; but you overlook the fact that the same user (in Java, where getters and setters are everywhere) does not expect (observable) “side effects” as a result of calling the setter (or even less for the getter ;-). They are reasonable expectations, and you, as the author of the class, try to fit them - regardless of whether your setter and getter are used directly or through a property, it does not matter. If you have methods with important observable side effects, do not call them getThis , setThat and do not use them through properties.
The complaint that the "hide implementation" properties is completely unfounded: most OOPs are information hiding implementations - creating a class responsible for representing the logical interface to the outside world and its implementation as best as possible. Getters and setters, like properties, are tools to achieve this. Properties simply improve performance (in languages that support them;).