0

Here is a simple class with a customized __getattr__ implementation:

class Wrapper(object):
    def __init__(self, obj):
        self.obj = obj

    def __getattr__(self, name):
        func = getattr(self.__dict__['obj'], name)
        if callable(func):
            def my_wrapper(*args, **kwargs):
                print "entering"
                ret = func(*args, **kwargs)
                print "exiting"
                return ret
            return my_wrapper
        else:
            return func

What I don't understand here is why getattr(self.__dict__['obj'], name) is used instead of getattr(self.obj, name) which is more concise?

Because as far as I can see what self.__dict__['obj'] does is invoke the value of self.obj. May it have anything to do with backward compatibility?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Albert
  • 2,146
  • 10
  • 32
  • 54
  • It doesn't invoke it - but it does access it. `__dict__` is a low level python detail that probably shouldn't be accessed unless you know what you're doing, so your counter example of using `getattr` would be preferable under most circumstances. – Shadow Feb 11 '19 at 23:59
  • 3
    `self.obj` would invoke `__getattr__` again which would lead to infinite recursion. Using `__dict__` breaks that cycle. – mkrieger1 Feb 12 '19 at 00:01
  • @juanpa.arrivillaga I've edited my question taking this into account. Thank you for pointing that out. – Albert Feb 12 '19 at 00:16

1 Answers1

2

I believe, the reason for this code to exist – author tried to evade endless recursion loop – to not trigger __getattr__ by self.obj

Slam
  • 8,112
  • 1
  • 36
  • 44