An even lower-level attribute processing is the __getattribute__() method. The default implementation of this method attempts to locate the value as an existing attribute in the internal __dict__ (or __slots__). If the attribute is not found, this method calls __getattr__() as a fallback. If the value located is a descriptor (refer to the following Creating descriptors section), then it processes the descriptor. Otherwise, the value is simply returned.
By overriding this method, we can perform any of the following kinds of tasks:
- We can effectively prevent access to attributes. This method, by raising an exception instead of returning a value, can make an attribute more secret than if we were to merely use the leading underscore (_) to mark a name as private to the implementation.
- We can invent new attributes similarly to how __getattr__() can invent...