classDelegator:# The cache is only used to be able to change delegates!def__init__(self,delegate=None):self.delegate=delegateself.__cache={}def__getattr__(self,name):attr=getattr(self.delegate,name)# May raise AttributeErrorsetattr(self,name,attr)self.__cache[name]=attrreturnattrdefresetcache(self):forkeyinself.__cache.keys():try:delattr(self,key)exceptAttributeError:passself.__cache.clear()defcachereport(self):keys=self.__cache.keys()keys.sort()printkeysdefsetdelegate(self,delegate):self.resetcache()self.delegate=delegatedefgetdelegate(self):returnself.delegate