问题描述
我有许多数据类,它们都继承自一个基类。 mapping
应该动态添加到每个子类中,然后由描述符的 __set_name__
使用以在其中设置一个键。
这是这个结构的样子:
class Model:
def __init_subclass__(cls,*args,**kwargs):
cls.mapping = {}
@dataclass
class ModelA(Model):
property: str = Descriptor()
class Descriptor:
def __set_name__(self,owner,name):
owner.mapping[name] = 'foobar'
当描述符的 mapping
被调用时,似乎 __set_name__
不存在。我尝试为 ModelA
使用元类:
class Meta(type):
def __new__(cls,name,bases,dict):
dict['mapping'] = {}
return super().__new__(cls,dict)
但是还是不行。
关于我的层次结构是如何构建的,我在这里缺少什么?我怎样才能达到我所追求的加载顺序?
注意我使用的是 Python 3.8.5
解决方法
__set_name__
发生在 __init_subclass__
之前。 Here's 记录在案的地方:
当使用默认元类 type
或任何最终调用 type.__new__
的元类时,在创建类对象后会调用以下额外的自定义步骤:
-
首先,
type.__new__
收集类命名空间中定义__set_name__()
方法的所有描述符; -
其次,所有这些
__set_name__
方法都使用正在定义的类和该特定描述符的指定名称来调用; -
最后,
__init_subclass__()
钩子按照新类的方法解析顺序在其直接父类上调用。