将函数分配给对象属性 [英] Assigning a function to an object attribute

查看:26
本文介绍了将函数分配给对象属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于我对Python 的数据模型的理解,特别是在实例方法"小节中,每当您读取值为用户定义函数"类型的属性时,就会出现一些魔法,您将获得绑定实例方法而不是实际的原始函数.这就是为什么在调用方法时不显式传递 self 参数的原因.

Based on my understanding of Python's data model, and specifically the subsection "Instance Methods", whenever you read an attribute whose value is of type "user-defined function", some magic kicks in and you get a bound instance method instead of the actual, original function. That magic is why you don't explicitly pass the self parameter when you're calling a method.

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

But then, I would expect to be able to replace an object's method with a function with the same signature:

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 属性时,我希望魔法开始并给我一个不带参数的绑定实例方法(就像我没有替换 时得到的一样)脚本).相反,它似乎返回了我传入的完全相同的函数、self 参数等.方法绑定魔法没有发生.

I'm creating an instance of Scriptable, and setting its script attribute to a user-defined function with a single parameter, just like what's defined in the class. So when I read the scriptable.script attribute, I would expect the magic to kick in and give me a bound instance method that takes no parameters (just like I get when I didn't replace script). Instead, it seems to be giving back the exact same function I passed in, self parameter and all. The method-binding magic isn't happening.

为什么当我在类声明中定义方法时,方法绑定魔法会起作用,而在分配属性时却不起作用?是什么让 Python 以不同的方式对待这些情况?

Why does the method-binding magic work when I define a method inside the class declaration, but not when I assign the attribute? What makes Python treat these situations differently?

如果 Python3 有什么不同,我会使用它.

I'm using Python3 if it makes any difference.

推荐答案

这是你的方法:

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 对象中.当您从实例访问属性时,类对象上的描述符将函数作为绑定方法返回.

As ba__friend noted in the comments, methods are stored on the class object. A descriptor on the class object returns functions as bound methods when you access the attribute from a instance.

当你将一个函数分配给一个 instance 时,没有什么特别的事情发生,所以你必须自己包装这个函数.

When you assign a function to a instance nothing happens special happens, so you have to wrap the function yourself.

这篇关于将函数分配给对象属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆