assume unknown names are errorsreplace __getattr__ with this def __getattribute__(selfattr)print('getattrif attr ='name'attr '_namereturn object __getattribute__(selfattron [obj anyintercept all names map to internal name avoid looping here when run with this changethe output is similarbut we get an extra __getattri bute__ call for the fetch in __setattr__ (the first time originating in __init__) :\codepy - getattribute-person py set_name get__dict__ getname bob smith setname get__dict__ getname robert smith delname get__dict__ set_name get__dict__ getname sue jones this example is equivalent to that coded for properties and descriptorsbut it' bit artificialand it doesn' really highlight these toolsassets because they are generic__getattr__ and __getattribute__ are probably more commonly used in delegationbase code (as sketched earlier)where attribute access is validated and routed to an embedded object where just single attribute must be managedproperties and descriptors might do as well or better computed attributes as beforeour prior example doesn' really do anything but trace attribute fetchesit' not much more work to compute an attribute' value when fetched as for properties and descriptorsthe following creates virtual attribute that runs calculation when fetchedclass attrsquaredef __init__(selfstart)self value start def __getattr__(selfattr)if attr =' 'return self value * elsetriggers __setattr__on undefined attr fetch value is not undefined __getattr__ and __getattribute__