如何在__getattr__内部传递参数

时间:2018-09-30 07:57:10

标签: python python-3.x delegates

我了解__getattr__方法的基本功能和用例。但是我在__getattr__内部如何传递参数时遇到麻烦。

我有代码

class Wrapper:
    def __init__(self, object):
        self.wrapped = object
    def __getattr__(self, attrname):
        print('trace: ' + attrname)
        return getattr(self.wrapped, attrname)


x = Wrapper([1, 2, 3])
x.append(4)
print(x.wrapped)

它会打印

trace: append
[1, 2, 3, 4]

如果我的以下假设不正确,请原谅我。我假设4中的参数x.append(4)从最初的调用传递到__getattr__,然后传递到getattr方法的调用,再传递到append list类的方法。但是我不确定到底发生了什么。有人可以澄清细节。

2 个答案:

答案 0 :(得分:3)

这是我的理解方式:

x = Wrapper([1, 2, 3])

因此,x.wrappedlist,即[1, 2, 3]

现在,当您执行x.append时,将用参数__getattr__调用Wrapper中的append。因此,当python解析时:

getattr(self.wrapped, attrname)

它获取内部列表的方法append,然后将其返回。因此,您可以想象您的代码被解释为:

# just got it outside for later explanation
l = [1, 2, 3]

x = Wrapper(l)

f = x.__getattr__('append')
# here `f` is the `append` method of `l`

f(4) # which is equivalent to `l.append(4)`

# finally
print(x.wrapped)
# which is equivalent to `print(l)`, hence the output
# [1, 2, 3, 4]

希望有帮助。

答案 1 :(得分:1)

__getattr__从未与该4联系。 __getattr__仅返回一个绑定方法,然后使用参数4调用该方法。 获得绑定方法和调用绑定方法是两个不相关的步骤,__getattr__仅负责第一个步骤。

如果您在脑海中划分了这一行,可能会更容易遵循:

x.append(4)

分为两个:

method = x.append  # obtain the bound method
method(4)          # call the bound method

很明显,__getattr__在第一行中被调用,与第二行无关。 __getattr__仅返回对包装列表的append方法的引用,因为您可以轻松地自己进行验证:

>>> x.append
<built-in method append of list object at 0x7f096feb2fc8>

这是绑定方法。绑定方法只是一种引用对象的方法,该对象将在调用该方法时代替self(在这种情况下,列表为x.wrapped)。绑定方法是我们可以在不显式传递self参数的情况下调用方法的原因。

有关绑定方法的更多详细信息,请参见What is the difference between a function, an unbound method and a bound method?