如何在方法的__init__方法中将方法绑定到类?

时间:2014-02-27 15:12:32

标签: python

最终修改

我的问题是我试图将一个部分绑定到一个类。不确定我是否应删除此问题或更改其标题。

原始问题

我知道the "correct" way将方法绑定到其元类中的类是将其添加到元类的classdict方法中的__new__参数中,并且通常可以绑定一个通过简单地将类赋值给类的实例方法。

但是,在我的用例中,我需要在元类的__init__方法中将方法绑定到类。问题是通常的分配方法不起作用。该函数已分配给该类,它可以通过ClassName.function_nameclass_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

所以,显然问题出现了,因为我试图绑定一个部分。不确定为什么会导致问题。

稍后会确定,并在必要时更新/删除此问题。

2 个答案:

答案 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中是否有变化。