python - __annotations__ 类中条目的顺序是否与其定义一致?

标签 python annotations

假设我们有一个类定义:

class A:
    z: 1
    b: 2
    Z: 3
    g: 4
    C: 5
    A: 6
    d: 7

标准 CPython 为 A.__annotations__ 提供了这个值:

{
    'z': 1,
    'b': 2,
    'Z': 3,
    'g': 4,
    'C': 5,
    'A': 6,
    'd': 7
}

总是这样吗?规范对此有何规定?

最佳答案

PEP 526 中给出的变量注释语法规范陈述如下:

at the module or class level, if the item being annotated is a simple name, then it and the annotation will be stored in the __annotations__ attribute of that module or class (mangled if private) as an ordered mapping from names to evaluated annotations.

因此默认似乎保证了有序映射。但是,PEP 还声明了以下内容:

__annotations__ is writable ... But attempting to update __annotations__ to something other than an ordered mapping may result in a TypeError ... (Note that the assignment to __annotations__ ... is accepted by the Python interpreter without questioning it - but the subsequent type annotation expects it to be a MutableMapping ...)

因此,由于 MutableMapping 本身并不是有序的,因此第三方类的 __annotations__ 至少有可能是一个映射,它定义了一个任意的顺序:

from collections.abc import MutableMapping

class D(MutableMapping):
    def __init__(self, *args):
        self._d = {}

    def __getitem__(self, key):
        return self._d[key]

    def __setitem__(self, key, value):
        self._d[key] = value

    def __delitem__(self, key):
        del self._d[key]

    def __iter__(self):
        return reversed(self._d)

    def __len__(self):
        return len(self._d)


class A:
    __annotations__ = D()
    z: 1
    b: 2
    Z: 3
    g: 4
    C: 5
    A: 6
    d: 7

for item in A.__annotations__.items():
    print(item)
('d', 7)
('A', 6)
('C', 5)
('g', 4)
('Z', 3)
('b', 2)
('z', 1)
    
    

关于python - __annotations__ 类中条目的顺序是否与其定义一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64444638/

相关文章:

java - 如何使@Documented注释保留泛型信息?

python - 需要以0.25的倍数四舍五入

Python:避免分数简化

java - 为什么@AfterSuit 在没有alwaysRun=true 的情况下不运行?

java - ProGuard 忽略注释默认值

java - Spring bean 不使用@Component 注释 Autowiring

jquery - 如何从 ajax POST 表单提交中使用 Flask 的 render_template

python - 如何更改 numpy 数组中的数据 block

python - Pandas 计算行中逐年(或任何其他索引)的变化

doctrine-orm - Symfony2 Doctrine 未找到不同 bundle 的映射父类(super class)注释