最终修改
我的问题是我试图将一个部分绑定到一个类。不确定我是否应删除此问题或更改其标题。
原始问题
我知道the "correct" way将方法绑定到其元类中的类是将其添加到元类的classdict
方法中的__new__
参数中,并且通常可以绑定一个通过简单地将类赋值给类的实例方法。
但是,在我的用例中,我需要在元类的__init__
方法中将方法绑定到类。问题是通常的分配方法不起作用。该函数已分配给该类,它可以通过ClassName.function_name
或class_instance.function_name
进行访问,但它不绑定到该类,并且第一个参数未设置为self
。
我想这是因为在元类__init__
期间没有完全初始化类,但有没有办法解决这个问题?
编辑:代码示例
假设:
def fun(self):
pass
class MetaClass(type):
def __init__(cls, name, bases, dct):
pass
class Class(object):
__metaclass__ = MetaClass
我想将fun
绑定到Class
内的MetaClass.__init__
,以便调用
instance = Class()
instance.fun()
将instance
作为第一个参数传递给fun
。
编辑II
所以,显然问题出现了,因为我试图绑定一个部分。不确定为什么会导致问题。
稍后会确定,并在必要时更新/删除此问题。
答案 0 :(得分:4)
metaclass.__new__()
和metaclass.__init__()
之间几乎没有区别;他们都处理类对象。
__new__
生成新对象__init__
然后仍然可以改变它。事件链基本上是:
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__
如果要在类上添加常规函数对象,则在实例上访问时它们将被绑定,无需您的工作。
底线是你需要添加某些,它将扮演descriptor,特别是一个将从descriptor.__get__
方法返回一个方法对象的描述符。这是普通函数对象的作用。
functools.partial()
对象不这样的描述符。最简单的方法是将部分包装在一个函数中(lambda
将在这里执行):
new_class_obj.name = lambda *args, **kw: partial_obj(*args, **kw)
答案 1 :(得分:-1)
问题是元类__new__
已经调用了type.__new__
,这就是将类字典中的函数转换为未绑定方法作为构造类对象的一部分。
您可以使用types
模块构建方法。您的代码看起来像这样:
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中是否有变化。