gpt4 book ai didi

python 3 : When is a call to an instance attribute resolved as if it is an instance method?

转载 作者:太空狗 更新时间:2023-10-30 03:05:34 26 4
gpt4 key购买 nike

class C:
def func(self, a):
print(a)

c = C()
print(c.__dict__) # {}
c.func = c.func
# c.func is now an instance attribute, which hides instance method
print(c.__dict__) # {'func' : (bound method C.f of (__main.C object at ...))}
# how come it still works as if it's an instance method:
c.func(1) # prints 1

# with a regular function assigned to c.func, this won't happen:
def newfunc(self, a):
print(a)
c.func = newfunc
c.func(1) # TypeError

调用 c.func(1) 神奇地将实例 c 添加为第一个参数的条件是什么?我认为只有当 func 被定义为类中的实例方法时才会发生。但它似乎有时func 只是一个实例属性时起作用。

最佳答案

实例的绑定(bind)发生在您访问 c.func ,而不是当你调用它时。当你做 c.func = c.func , 右侧的属性访问由类 C 处理并评估绑定(bind)方法。将其重新分配给 c.func将它分配给实例,但它已经是一个绑定(bind)方法,所以这不会改变行为。

在您的 newfunc 示例中,您只是定义了一个函数并对其进行了分配,因此它永远不会成为实例方法。由于您将它直接分配给一个实例,该类没有机会拦截访问并将其包装在实例方法中。

你可以在任何你喜欢的地方分配一个绑定(bind)方法,它仍然绑定(bind)到你通过它获得它的实例。请参阅以下示例:

>>> class C(object):
... def __init__(self, name):
... self.name = name
... def func(self, a):
... print("Called {0} with {1}".format(self.name, a))
>>> one = C("one")
>>> two = C("two")
>>> one.func(1)
Called one with 1
>>> two.func(1)
Called two with 1
>>> one.func2 = two.func
>>> one.func2(1)
Called two with 1

请注意,一旦我分配了 one.func2 = two.func , 调用 one.func2调用绑定(bind)到 two 的实例方法, 不是 one .这是因为当我访问 two.func ,我得到了一个绑定(bind)到该实例的方法。我稍后将它分配到哪里并不重要。它仍然绑定(bind)到访问它的实例。

如果您直接访问未绑定(bind)的方法并尝试将其分配到别处,那么您会得到 TypeError,因为该方法从未被绑定(bind):

>>> one.func3 = C.func
>>> one.func3(1)
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
one.func3(1)
TypeError: unbound method func() must be called with C instance as first argument (got int instance instead)

另请注意,如果您将方法添加到,则在实例上调用时它将起作用,即使该实例是在您将方法添加到类之前创建的。保持不变one之前的对象,我可以这样做:

>>> def newFunc(self, a):
... print("Newfunc of {0} called with {1}".format(self.name, a))
>>> C.newFunc = newFunc
>>> one.newFunc(1)
Newfunc of one called with 1

为了简洁地回答您的问题,c.func绑定(bind)到 c如果c是具有方法 func 的类的实例, 和 c本身没有实例属性 func . (如果 c 确实有一个同名的实例属性,它会覆盖类一,因此类不会进行包装以将方法绑定(bind)到实例。)

关于 python 3 : When is a call to an instance attribute resolved as if it is an instance method?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11748930/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com