- Mastering Objectoriented Python
- Steven F. Lott
- 266字
- 2021-11-12 16:25:14
Summary, design considerations, and trade-offs
In this chapter, we looked at several ways to work with an object's attributes. We can use the built-in features of the object
class and get and set attribute values. We can define properties to modify how attributes behave.
If we want more sophistication, we can tweak the underlying special method implementations for __getattr__()
, __setattr__()
, __delattr__()
, or __getattribute__()
. These allow us very fine-grained control over attribute behaviors. We walk a fine line when we touch these methods because we can make fundamental (and confusing) changes to Python's behavior.
Internally, Python uses descriptors to implement features such as method functions, static method functions, and properties. Many of the cool use cases for descriptors are already first-class features of the language.
Programmers coming from other languages (particularly Java and C++) usually have the urge to try to make all attributes private and write extensive getter and setter functions. This kind of coding is necessary for languages where type definitions are statically compiled in.
In Python, it's considerably simpler to treat all attributes as public. This means the following:
- They should be well documented.
- They should properly reflect the state of the object; they shouldn't be temporary or transient values.
- In the rare case of an attribute that has a potentially confusing (or brittle) value, a single leading underscore character (
_
) marks the name as "not part of the defined interface." It's not really private.
It's important to think of private attributes as a nuisance. Encapsulation isn't broken by the lack of complex privacy mechanisms in the language; it is broken by bad design.