-1

Recently, I saw the code below as an answer to a problem:

class Proxy:
    def __init__(self, obj):
        self._obj = obj

    def __getattr__(self, attr):
        try:
            value = getattr(self._obj, attr)
        except Exception:
            raise Exception('No Such Method')
        else:
            return value

class Tmp:
    def __init__(self, num):
        self.num = num

    def set_num(self, num):
        self.num = num
        print(self.num)

tmp = Tmp(10)
tmp_proxy = Proxy(tmp)
tmp_proxy.set_num(12)

As you can see, it uses tmp_proxy to call set_num() method of object tmp. But I can't understand how it passes the argument num to this method, because as we print attr and its type, we see this:

set_num
<class 'str'>

How does this work?

Armaho
  • 37
  • 5
  • What exactly isn't clear? if you remove `return ...` from `__getattr__` then it will implicitly return `None` for any `.` notation access so `tmp_proxy.set_num` is `None`. Also, the title and the question are not related – DeepSpace Sep 13 '22 at 14:20
  • Try to add some breakpoints and debug your code step by step – DeepSpace Sep 13 '22 at 14:23

1 Answers1

0

tmp_proxy doens't call set_num; it provides a reference to the appropriate bound method. value is that bound method, not the return value. You could rewrite this code more explicitly:

f = tmp_proxy.set_num  # get a bound method
f(12)  # call the bound method
chepner
  • 497,756
  • 71
  • 530
  • 681