我了解__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
类的方法。但是我不确定到底发生了什么。有人可以澄清细节。
答案 0 :(得分:3)
这是我的理解方式:
x = Wrapper([1, 2, 3])
因此,x.wrapped
是list
,即[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?。