使用元类“__init__”与“__new__”动态添加方法

Dynamically adding methods with metaclass "__init__" vs "__new__"

继续这个问题的讨论: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)

If you do this in the new method, you need to modify the dict parameter

嗯,不一定,你也可以在创建新的class对象后使用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__中你只能修改已经实例化的class对象,而在Meta.__new__中你可以在之前检查和修改父对象和命名空间 创建 class 之后修改创建的 class。

那么使用 __init__ 有什么意义呢?好吧,有时你不需要 __new__ 的所有功能,你只想修改新创建的 class,然后 __init__ 为你节省了创建 class 的额外样板.