在元类构造函数(__new__
和__init__
)中创建类的实例有多安全?我特别感兴趣的是Python 2.7,但是Python 3的功能也很受欢迎。
Python data model docs声音就像他们为正常的类实例创建案例编写的那样,我不确定规则在元类中发生时会有多么微妙的差异。
例如,假设我有这样的代码:
class Meta(type):
NEWED = []
INITED_BEFORE = []
INITED_AFTER = []
def __new__(meta, name, bases, dict):
cls = super(Meta, meta).__new__(meta, name, bases, dict)
instance = cls()
Meta.NEWED.append(instance)
return cls
def __init__(cls, name, bases, dict):
Meta.INITED_BEFORE.append(cls())
super(Meta, cls).__init__(name, bases, dict)
Meta.INITED_AFTER.append(cls())
class Foo(object):
__metaclass__ = Meta
在元数据构建它的时候,在哪些点(如果有的话)构造Foo的实例是安全的,还有什么样的警告?
我怀疑的是,如果Foo继承了其他类,或者是子类,而其他类都有自己的元类,那么在任何元类方法中调用cls()
都会调用它 - 尚未完成的类对象。这是真的吗?
答案 0 :(得分:0)
我怀疑的是,如果Foo继承了其他类,或者是子类,而其他类都有自己的元类,那么在任何元类方法中调用cls()都会调用它。完成的类对象。这是真的吗?
确实如此,在元类的__new__
中,它的__init__
还没有被调用。你的元类有一个__init__
,就像任何子类一样,所以你应该确保首先调用它。所以我不会尝试创建一个尚未完全实例化的类的实例。
您可能要做的一件事是从__init__
内手动调用元类的__new__
。但您必须在__init__
中设置一个标记或内容,以确保该类不会__init__
'两次。可能还有一种更聪明的方式,我现在还没想到。