使用元类的 "__init__" 和 "__new__" 动态添加方法的区别

7

继续讨论这个问题:Dynamically adding methods with or without metaclass,在进行动态注入时,在__new__方法和__init__方法中进行有何区别、好处和问题?

在参考的问题中,新方法是使用setattr添加的。如果您在__new__方法中这样做,则需要修改dict参数。以同样的示例为例,代码如下:

class Meta(type)
    def __new__(cls, clsname, bases, dct):
        def my_method(self, x):
            return x in self.letters

        dct[my_method.__name__] = my_method
        return super(Meta, cls).__new__(cls, clsname, bases, dct)
1个回答

12

如果您使用新方法进行此操作,您需要修改dict参数。

但不一定需要,您也可以在创建新类对象后使用setattr ,如下所示:

class Meta(type)
    def __new__(cls, clsname, bases, dct):
        def my_method(self, x):
            return x in self.letters

        newclass =  super(Meta, cls).__new__(cls, clsname, bases, dct)
        setattr(newclass, my_method.__name__, my_method)
        return newclass

基本上,在 Meta.__init__ 中,你只能修改已经实例化的类对象,而在 Meta.__new__ 中,你可以在创建类之前检查和修改父级和命名空间,并且可以在创建后修改创建的类。

那么使用 __init__ 的意义是什么呢?有时候你不需要 __new__ 给你的所有权限,你只想修改新创建的类,这时使用 __init__ 可以省去创建类的额外代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接