使用元类“__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 的额外样板.
继续这个问题的讨论: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 的额外样板.