我想实现这种情况 - 我有一个类,那里有一些包含外部方法的变量,在某些情况下可以重新定义方法。它可能看起来像:
def my_print(self):
print('my print is called')
class example():
some_method = my_print
def __init__(self):
self.some_method()
def test(self):
self.some_method()
所以,它有效:
a = example()
a.test()
结果如下:
my print is called (from init)
my print is called (from test)
但如果重新定义some_method
:
a = example()
a.some_method = my_print
a.test()
它返回一个错误,表示我需要在 self.some_method()
行中提供 self
作为参数:
TypeError: my_print() missing 1 required positional argument: 'self'
为什么会发生这种情况,也许有人知道解决这个问题的技巧?
最佳答案
这是 .
在 Python 中的微妙之处。它既查找类上的方法,又将该方法绑定(bind)到实例。此绑定(bind)隐式提供类实例作为第一个参数 self
。看看这个:
>>> print(example.some_method)
<function my_print at 0x7f66c4129f30>
>>> print(a.some_method)
<bound method my_print of <test.example object at 0x7f66c41c2290>>
但是,当在实例上找到该方法时(它隐藏了类上的方法),绑定(bind)不会发生:
>>> a = example()
my print is called
>>> a.some_method = my_print
>>> print(a.some_method)
<function my_print at 0x7f66c4129f30>
这在 Python reference 中有说明。 :
It is also important to note that user-defined functions which are attributes of a class instance are not converted to bound methods; this only happens when the function is an attribute of the class.
解决方案是确保该方法始终是类实例的属性,并相应地调用它:
class example():
def __init__(self):
self.some_method = my_print
self.some_method(self)
def test(self):
self.some_method(self)
看起来很奇怪,但效果很好。
如果您希望该方法始终是类的一个属性,请考虑使用继承。
关于python-3.x - 类方法重新定义, 'self' 参数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71292923/