__init_subclass__ 和描述符 __set_name__ 的顺序

问题描述

我有许多数据类,它们都继承自一个基类。 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__() 钩子按照新类的方法解析顺序在其直接父类上调用。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...