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中给出的变量注释语法规范说明了以下内容:
在模块或类级别,如果被注释的项目是一个简单的名称,那么它和注释将
__annotations__
作为从名称到评估的注释的有序映射存储在该模块或类的属性中(如果私有则被破坏)。
因此,默认情况下似乎可以保证有序映射。但是,PEP 还声明了以下内容:
__annotations__
是可写的...但是尝试更新__annotations__
到有序映射以外的其他内容可能会导致 TypeError ...(请注意,对__annotations__
... 的赋值被 Python 解释器接受而不会质疑它 - 但随后的类型注释需要它成为一个 MutableMapping ...)
因此,由于 aMutableMapping
本身不是有序的,因此__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)
推荐阅读
- docker - 如何在 docker 主机和 docker 容器之间共享端口 8080 而不会发生端口冲突?
- powershell - 使用 PowerShell 将服务总线队列消息内容转换为字符串
- php - 如何忽略库中的主要自动递增列 (ifsnop / mysqldump-php)
- json - .NET CORE 3.1 Razor 页面调用 API 在 IIS 服务器上不返回任何内容 在本地返回数据
- jquery - Laravel 7 Ajax 请求变量为空
- maven - 如何定义 Maven 的环境变量来定义本地存储库和包装器下载位置?
- css - 使用shape-outside包装时如何将img与文本底部对齐
- google-bigquery - Python Beam Airflow 未创建 BigQuery 分区表
- video.js - 如何在视频播放器之外显示 video.js 控件
- javascript - 为什么 NavLink 将我重定向到 React 组件的末尾部分