首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将函数分配给对象属性

将函数分配给对象属性
EN

Stack Overflow用户
提问于 2011-06-25 22:28:08
回答 4查看 9.1K关注 0票数 23

根据我对Python's data model的理解,特别是“实例方法”这一小节,每当你读取值为“用户定义函数”类型的属性时,就会有一些神奇的事情发生,你会得到一个绑定的实例方法,而不是实际的原始函数。这就是为什么在调用方法时不显式传递self参数的原因。

但是,我希望能够用具有相同签名的函数替换对象的方法:

代码语言:javascript
复制
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。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-25 23:01:22

下面是你如何做到这一点:

代码语言:javascript
复制
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时,没有什么特别的事情发生,所以你必须自己包装这个函数。

票数 17
EN

Stack Overflow用户

发布于 2011-06-26 03:03:14

多亏了Alex Martelli的answer,下面是另一个版本:

代码语言:javascript
复制
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()
票数 11
EN

Stack Overflow用户

发布于 2011-06-25 22:46:10

看看这个:

代码语言:javascript
复制
>>> 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

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6478371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档