0

I am stuck in a problem with delegation in Python. I read a program as following:

class wrapper:
    def __init__(self,object):
        self.wrapped=object
    def __getattr__(self,attrname):             #reload the dot-calculation
        print('Trace:', attrname)               #print the attribute of the object
        return getattr(self.wrapped, attrname)  #execute the attributes of the object
i=[1,2,3]                                       
myWrapper=wrapper(i)                            
wrapper.wrapped                                 #execute the dot-calculation
wrapper.append(4)                               #execute the dot-calculation

In my opinion, both of these two executions of the dot-calculation should print 'Trace'. However, I only get Trace for one time.

wrapper.wrapped     #never print 'Trace'
wrapper.append(4)   #print ('Trace:', append')

I can't understand this. Is funtion__getattr__ reloaded or not? Why there is nothing printed during the first execution?

Thanks for your explanation!

Harry
  • 77
  • 8
  • 7
    `__getattr__` is just a fallback. `wrapped` is actually found in the object's `__dict__`, so `__getattr__` is never called. See https://stackoverflow.com/questions/3278077/difference-between-getattr-vs-getattribute. If it were called, you'd ahve infinite recursion since `self.wrapped` is invoked within `__getattr__` – user2390182 Jul 17 '18 at 07:53
  • If you want to unconditionally call a special method when looking up attributes, then you want `__getattribute__` rather than `__getattr__`. But note that you need to be careful if you go that route. The `self.wrapped` lookup in your current implementation would lead you into infinite recursion (until you hit the system recursion limit). You'd need to use `super().__getattribute__('wrapped')` or similar to avoid that issue. Or, you know, just accept that you don't proxy the name `wrapped` (you could pick another name if you want). Name mangling (e.g. `__wrapped`) is designed for exactly this. – Blckknght Jul 17 '18 at 07:57
  • @schwobaseggl I get it! Thanks for your link! Thanks! – Harry Jul 17 '18 at 08:00
  • @Blckknght Thanks for your suggestion! – Harry Jul 17 '18 at 08:01
  • @khelwood oh! I am reading the link. It helps! – Harry Jul 17 '18 at 08:04

0 Answers0