The crucial importance of properties is that their existence makes it perfectly safe and indeed advisable for you to expose public data attributes as part of your class’s public interface.
— Alex Martelli Python contributor and book author
Data attributes and methods are collectively known as attributes in Python: a method is just an attribute that is callable. Besides data attributes and methods, we can also create properties, which can be used to replace a public data attribute with accessor methods (i.e., getter/setter), without changing the class interface. This agrees with the Uniform access principle:
All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.
Besides properties, Python provides a rich API for controlling attribute access and implementing dynamic attributes. The interpreter calls special methods such as
__setattr__ to evaluate attribute access using dot notation (e.g.,
obj.attr). A user-defined class implementing
__getattr__ can implement “virtual attributes” by computing values on the fly whenever somebody tries to read a nonexistent attribute like
Coding dynamic attributes is the kind of metaprogramming that framework authors do. However, in Python, the basic techniques are so straightforward that anyone can put them to work, even for everyday data wrangling ...