def __getattr__(selfattr)return getattr(self personattrdef __repr__(self)return str(self personintercept and delegate delegate all other attrs must overload again (in xif __name__ ='__main__'sue person('sue jones'job='dev'pay= print(sue lastname()sue giveraise print(suetom manager('tom jones' manager __init__ print(tom lastname()manager __getattr__ -person lastname tom giveraise manager giveraise -person giveraise print(tommanager __repr__ -person __repr__ comments at the end of this file show which methods are invoked for line' operation in particularnotice how lastname calls are undefined in managerand thus are routed into the generic __getattr__ and from there on to the embedded person object here is the script' output--sue receives raise from personbut tom gets because giveraise is customized in managerc:\codepy - getattr-delegate py jones [personsue jones jones [persontom jones by contrastthoughnotice what occurs when we print manager at the end of the scriptthe wrapper class' __repr__ is invokedand it delegates to the embedded person object' __repr__ with that in mindwatch what happens if we delete the man ager __repr__ method in this codedelete the manager __str__ method class managerdef __init__(selfnamepay)self person person(name'mgr'paydef giveraise(selfpercentbonus )self person giveraise(percent bonusdef __getattr__(selfattr)return getattr(self personattrembed person object intercept and delegate delegate all other attrs now printing does not route its attribute fetch through the generic __getattr__ interceptor under python ' new-style classes for manager objects insteada default __repr__ display method inherited from the class' implicit object superclass is looked up and run (sue still prints correctlybecause person has an explicit __repr__) :\codepy - getattr-delegate py jones [personsue jones jones managed attributes