Python 如何在元类期间将方法绑定到类';s_u_初始方法?
最终编辑 我的问题是,我试图将一个分部绑定到一个类。不确定我是否应该删除此问题或更改其标题 原始问题 我知道,将方法绑定到其元类中的类就是将其添加到元类的Python 如何在元类期间将方法绑定到类';s_u_初始方法?,python,Python,最终编辑 我的问题是,我试图将一个分部绑定到一个类。不确定我是否应该删除此问题或更改其标题 原始问题 我知道,将方法绑定到其元类中的类就是将其添加到元类的\uuuuu new\uuuuuuu方法中的classdict参数中,通常,您可以通过简单地将实例方法分配给类来将其绑定到类 然而,在我的用例中,我需要在元类的\uuuu init\uuu方法期间将一个方法绑定到一个类。问题是通常的分配方法不起作用。函数被分配给类,可以通过ClassName.function\u name或class\u in
\uuuuu new\uuuuuuu
方法中的classdict
参数中,通常,您可以通过简单地将实例方法分配给类来将其绑定到类
然而,在我的用例中,我需要在元类的\uuuu init\uuu
方法期间将一个方法绑定到一个类。问题是通常的分配方法不起作用。函数被分配给类,可以通过ClassName.function\u name
或class\u instance.function\u name
访问,但它没有绑定到类,并且第一个参数没有设置为self
我猜这是由于在元类\uuuu init\uuuu
期间类没有完全初始化,但是有没有办法解决这个问题
编辑:代码示例
鉴于:
def fun(self):
pass
class MetaClass(type):
def __init__(cls, name, bases, dct):
pass
class Class(object):
__metaclass__ = MetaClass
我想将fun
绑定到元类中的类
instance = Class()
instance.fun()
将实例
传递给fun
作为其第一个参数
编辑II
所以,很明显,问题出现了,因为我试图绑定一个部分。不知道为什么会引起问题
稍后将确保,并在必要时更新/删除此问题。元类之间没有什么区别。新的(
和元类。初始化(
);它们都处理类对象
\uuuu new\uuuu
生成新对象,\uuuuuu init\uuuuu
然后继续修改它。事件链基本上是:
new_class_obj = YourMeta.__new__(YourMeta, name, bases, bodydict)
YourMeta.__init__(new_class_obj, name, bases, bodydict)
在新类对象上添加函数时(通过bodydict
或直接通过类对象上的赋值),没有任何区别
如果在类对象上设置函数时遇到问题,则需要确保在该对象上设置实际的函数对象
例如,如果使用绑定方法,则需要展开该方法并仅提取函数:
new_class_obj.name = method_obj.__func__
如果您在类上添加常规函数对象,那么在实例上访问它们时,它们将被绑定,您不需要做任何工作
最重要的是,您需要添加一些可以充当描述符的东西,特别是一个描述符,它将从描述符返回一个method对象。这就是普通函数对象所做的
functools.partial()
对象不是这样的描述符。最简单的方法是将部分封装在函数中(此处使用lambda
即可):
问题是元类\uuuuuuuuuuuuuuuuuuuuuuuuu
已经调用了类型。\uuuuuuuuuuuuuuuuuuuuuuuuu
,这是将类字典中的函数转换为未绑定的方法,作为构建类对象的一部分
您可以使用类型
模块构造方法。您的代码如下所示:
import types
def fun(self):
pass
class MetaClass(type):
def __init__(cls, name, bases, dct):
cls.fun = types.MethodType(fun, None, cls)
class Class(object):
__metaclass__ = MetaClass
注意:这是针对python2的,我不知道这在python3中是否已更改。否,我正在类上设置实例方法<代码>\uuuu元类。\uuuu init\uuuu
在类声明上运行。在这一点上没有实例。@RomanLevin:那么该方法来自实例?那么它已经是一个绑定方法,但是绑定到另一个实例。你能发布代码吗?@RomanLevin:这还不够样本。将func
添加到cls
时,它是一个未绑定的函数。我不认为这还不够。我哪里不清楚?@RomanLevin:那它应该就行了。你在类上放置了一个未绑定的函数,当在该类的实例上访问它时,它将被绑定;最重要的是,它不是一个描述符。我明白了。我想我得研究一下描述符。谢谢。不,不是这样的。类字典包含普通函数对象。它将这些函数作为类上的属性或触发的实例上的属性进行访问(通过对象上的\uuuu getattribute\uuuuu
方法)。换句话说,类.fun
作为类执行<代码>类()。类字典不存储方法对象。type.\uuu new\uu
方法当然不存储新创建的类上的types.MethodType
对象。
import types
def fun(self):
pass
class MetaClass(type):
def __init__(cls, name, bases, dct):
cls.fun = types.MethodType(fun, None, cls)
class Class(object):
__metaclass__ = MetaClass