根据我对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)实例方法(就像我不替换script时得到的一样)。取而代之的是,它似乎还给了我传递的完全相同的功能,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/

10-12 21:21
查看更多