根据我对Python's data model的理解,特别是“实例方法”这一小节,每当你读取值为“用户定义函数”类型的属性时,就会有一些神奇的事情发生,你会得到一个绑定的实例方法,而不是实际的原始函数。这就是为什么在调用方法时不显式传递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属性时,我会期待魔术发挥作用,并为我提供一个不带参数的绑定实例方法(就像我没有替换script时一样)。相反,它似乎返回了我传入的完全相同的函数,self参数和所有函数。方法绑定的魔术并没有发生。
为什么当我在类声明中定义一个方法时,方法绑定魔术会起作用,而当我分配属性时却不起作用?是什么让Python以不同的方式对待这些情况?
如果有什么不同的话,我会使用Python3。
发布于 2011-06-25 23:01:22
下面是你如何做到这一点:
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对象上。当您从实例访问属性时,类对象上的描述符会将函数作为绑定方法返回。
当你把一个函数赋给一个instance时,没有什么特别的事情发生,所以你必须自己包装这个函数。
发布于 2011-06-26 03:03:14
多亏了Alex Martelli的answer,下面是另一个版本:
class Scriptable:
def script(self):
print(self)
print("greetings from the default script")
def another_script(self):
print(self)
print("greetings from the another script")
s = Scriptable()
s.script()
# monkey patching:
s.script = another_script.__get__(s, Scriptable)
s.script()发布于 2011-06-25 22:46:10
看看这个:
>>> scriptable = Scriptable()
>>> scriptable.script
<bound method Scriptable.script of <__main__.Scriptable instance at 0x01209DA0>>
>>> scriptable = Scriptable(my_script)
>>> scriptable.script
<function my_script at 0x00CF9730>语句self.script = script只创建一个类对象的属性,没有使用任何“魔法”。
类定义中的语句def script(self):创建一个特定于描述符的对象,该对象实际管理带有self参数的所有内容。
您可以在提到的数据模型参考中阅读有关Python语言描述符的更多信息:implementing-descriptors。
Raymond Hettinger撰写的另一篇关于Python中描述符的优秀文章:How-To Guide for Descriptors。
https://stackoverflow.com/questions/6478371
复制相似问题