advanced programming techniques def __getattr__(selfname)if name ="colors"return set(self __colorsclassname self __class__ __name__ if name in frozenset({"background""width""height"})return self __dict__[" {classname}__{name}format**locals())raise attributeerror("'{classname}object has no "attribute '{name}'format(**locals())if we attempt to access an object' attribute and the attribute is not foundpython will call the __getattr__(method (providing it is implementedand that we have not reimplemented __getattribute__())with the name of the attribute as parameter implementations of __getattr__(must raise an attributeerror exception if they do not handle the given attribute for exampleif we have the statement image colorspython will look for colors attribute and having failed to find itwill then call image __getattr__(image"colors"in this case the __getattr__(method handles "colorsattribute name and returns copy of the set of colors that the image is using the other attributes are immutableso they are safe to return directly to the caller we could have written separate elif statements for each one like thiselif name ="background"return self __background but instead we have chosen more compact approach since we know that under the hood all of an object' nonspecial attributes are held in self __dict__we have chosen to access them directly for private attributes (those whose name begins with two leading underscores)the name is mangled to have the form _classname__attributenameso we must account for this when retrieving the attribute' value from the object' private dictionary for the name mangling needed to look up private attributes and to provide the standard attributeerror error textwe need to know the name of the class we are in (it may not be image because the object might be an instance of an image subclass every object has __class__ special attributeso self __class__ is always available inside methods and can safely be accessed by __getattr__(without risking unwanted recursion note that there is subtle difference in that using __getattr__(and self __class__ provides access to the attribute in the instance' class (which may be subclass)but accessing the attribute directly uses the class the attribute is defined in one special method that we have not covered is __getattribute__(whereas the __getattr__(method is called last when looking for (nonspecialat