基于我对 Python's data model 的理解,特别是“实例方法”小节,每当您读取其值为“用户定义函数”类型的属性时,就会出现一些魔术,您会得到一个绑定(bind)的实例方法,而不是实际的原始函数。这就是为什么在调用方法时不显式传递 self
参数的原因。
但是,我希望能够用具有相同签名的函数替换对象的方法:
class Scriptable:
def __init__(self, script = None):
if script is not None:
self.script = script # replace the method
def script(self):
print("greetings from the default script")
>>> scriptable = Scriptable()
>>> scriptable.script()
greetings from the default script
>>> def my_script(self):
... print("greetings from my custom script")
...
>>> scriptable = Scriptable(my_script)
>>> scriptable.script()
Traceback (most recent call last):
...
TypeError: script() takes exactly 1 positional argument (0 given)
我正在创建 Scriptable
的实例,并将其 script
属性设置为具有单个参数的用户定义函数,就像在类中定义的一样。因此,当我阅读 scriptable.script
属性时,我希望魔法会发挥作用并给我一个不带参数的绑定(bind)实例方法(就像我没有替换 时得到的一样脚本
)。相反,它似乎返回了我传入的完全相同的函数、self
参数和所有。方法绑定(bind)魔法没有发生。
为什么当我在类声明中定义方法时方法绑定(bind)魔法起作用,但在分配属性时不起作用?是什么让 Python 以不同的方式处理这些情况?
如果有什么不同,我正在使用 Python3。
最佳答案
这是你的做法:
import types
class Scriptable:
def __init__(self, script = None):
if script is not None:
self.script = types.MethodType(script, self) # replace the method
def script(self):
print("greetings from the default script")
正如评论中的 ba__friend 所说,方法存储在 class
对象中。当您从实例访问属性时,类对象上的描述符将函数作为绑定(bind)方法返回。
当您将函数分配给 instance
时,不会发生任何特殊情况,因此您必须自己包装函数。
关于python - 将函数分配给对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6478371/