Python Frequently Asked Questions, Release 3.9.5 Chapter 2. Programming FAQ 28 Most$_{__setattr__()}$ implementations must modify$_{self.__dict__}$ to store local state for self without caus- ing an infinite recursion. Note that for more general cases delegation can get trickier. When attributes must be set as well as retrieved, the class must define a __setattr__() method too, and it must do so carefully. The basic implementation of$_{__setattr__()}$ is roughly equivalent to the following: Here the$_{UpperOut}$class redefines the$_{write()}$ method to convert the argument string to uppercase before calling the underlying$_{self._outfile.write()}$ method. All other methods are delegated to the underlying$_{self.}$ _outfile object. The delegation is accomplished via the$_{__getattr__}$ method; consult the language reference for more information about controlling attribute access. Python programmers can easily implement delegation. For example, the following class implements a class that behaves like a file but converts all written data to uppercase: Delegation is an object oriented technique (also called a design pattern). Let’s say you have an object$_{x}$ and want to change the behaviour of just one of its methods. You can create a new class that provides a new implementation of the method you’re interested in changing and delegates all other methods to the corresponding method of$_{x}$. 2.6.5 What is delegation? def search(obj): if isinstance(obj, Mailbox): ... # code to search a mailbox elif isinstance(obj, Document): ... # code to search a document elif ... classMailbox : def search(self): ... # code to search a mailbox classDocument : def search(self): ... # code to search a document obj.search() A better approach is to define a search() method on all the classes and just call it: classUpperOut : def __init__ (self, outfile): self._outfile=outfile def write(self, s): self._outfile.write(s.upper()) def __getattr__ (self, name): return getattr(self._outfile, name) classX : ... def __setattr__ (self, name, value): self.__dict__ [name] =value ...