Source

classDelegator:# The cache is only used to be able to change delegates!def__init__(self,delegate=None):self.delegate=delegateself.__cache=set()def__getattr__(self,name):attr=getattr(self.delegate,name)# May raise AttributeErrorsetattr(self,name,attr)self.__cache.add(name)returnattrdefresetcache(self):forkeyinself.__cache:try:delattr(self,key)exceptAttributeError:passself.__cache.clear()defsetdelegate(self,delegate):self.resetcache()self.delegate=delegate