基于我对Python数据模型的理解,特别是"实例方法"小节,每当您读取其值为"用户定义函数"类型的属性时,一些魔法就会启动并获得绑定实例方法而不是实际方法,原始功能.这就是为什么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)
Run Code Online (Sandbox Code Playgroud)
我正在创建一个实例Scriptable,并script使用单个参数将其属性设置为用户定义的函数,就像在类中定义的那样.因此,当我读取scriptable.script属性时,我会期待魔法开始并给我一个不带参数的绑定实例方法(就像我没有替换时那样script).相反,它似乎回馈了我传入的完全相同的函数,self参数和所有.方法绑定魔法没有发生.
当我在类声明中定义一个方法时,为什么方法绑定魔法工作,但是当我分配属性时却没有?是什么让Python对这些情况的区别对待?
如果它有任何区别,我正在使用Python3.
Joc*_*zel 16
这是你如何做到的:
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")
Run Code Online (Sandbox Code Playgroud)
正如评论中提到的ba _friend,方法存储在class对象上.当您从实例访问属性时,类对象上的描述符将函数作为绑定方法返回.
当你将一个函数分配给instance没有任何特殊情况发生时,你必须自己包装该函数.
感谢Alex Martelli的回答是另一个版本:
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()
Run Code Online (Sandbox Code Playgroud)
看这个:
>>> 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>
Run Code Online (Sandbox Code Playgroud)
Statement self.script = script只创建一个类对象的属性,没有任何"魔法".
def script(self):类定义中的语句创建一个描述符 - 实际使用self参数管理所有内容的特殊对象.
您可以在上面提到的数据模型参考:implements-descriptors中阅读有关Python中描述符的更多信息.
Raymond Hettinger的一篇关于Python描述符的精彩文章: Descriptors的操作指南.
| 归档时间: |
|
| 查看次数: |
7452 次 |
| 最近记录: |