如何在 Python 3.7+ 中注入 class-变量注解?
How to inject class-variable annotations in Python 3.7+?
在Python 3.7中,可以使用PEP 526中定义的以下语法来注释静态字段:
class A:
foo: int
在定义了 class 之后,我怎样才能做这些注释呢?我希望以下内容有效:
A.bar : float
然而,它似乎与第一个代码没有相同的效果。当我们查看 A
的 __dict___
时,这两个片段没有相同的效果。
在示例 1 和示例 2 之后 之后,我们得到相同的 __dict__
,即第二个示例必须在其他地方显示效果。创建的字典是:
>> pprint(A.__dict__):
mappingproxy({'__annotations__': {'foo': <class 'int'>}, # <-!
'__dict__': <attribute '__dict__' of 'A' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'A' objects>})
我不认为编辑 __annotations__
是实现我想要的目标的 "good" 方法,尤其是因为我不确定这是否是注册 foo
的唯一情况.
执行此操作的正确方法是什么?
实例和 class 属性的变量注释中使用的信息存储在 class 上的 __annotations__
映射中,这是一个可写的字典。
如果您想添加到存储在那里的信息,那么只需将您的新信息直接添加到该映射:
A.__annotations__['bar'] = float
A.bar: float
注释被 Python 丢弃 ,因为没有专门的位置来存储 annotated expressions 的信息;由静态类型检查器实现来决定该表达式是否有意义。
参见 PEP 526 的 Runtime Effects of Type Annotations section -- 变量注释的语法,定义此语法的文档:
In addition, 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.
以及来自 Python 参考文档的 Annotated assignment statements section:
For simple names as assignment targets, if in class or module scope, the annotations are evaluated and stored in a special class or module attribute __annotations__
that is a dictionary mapping from variable names (mangled if private) to evaluated annotations. This attribute is writable and is automatically created at the start of class or module body execution, if annotations are found statically.
A.bar
不是简单的名字,是表达式,所以不存储;如果您想在 __annotations__
映射中保留该信息以供运行时访问,那么手动设置它是唯一的选择。
在Python 3.7中,可以使用PEP 526中定义的以下语法来注释静态字段:
class A:
foo: int
在定义了 class 之后,我怎样才能做这些注释呢?我希望以下内容有效:
A.bar : float
然而,它似乎与第一个代码没有相同的效果。当我们查看 A
的 __dict___
时,这两个片段没有相同的效果。
在示例 1 和示例 2 之后 之后,我们得到相同的 __dict__
,即第二个示例必须在其他地方显示效果。创建的字典是:
>> pprint(A.__dict__):
mappingproxy({'__annotations__': {'foo': <class 'int'>}, # <-!
'__dict__': <attribute '__dict__' of 'A' objects>,
'__doc__': None,
'__module__': '__main__',
'__weakref__': <attribute '__weakref__' of 'A' objects>})
我不认为编辑 __annotations__
是实现我想要的目标的 "good" 方法,尤其是因为我不确定这是否是注册 foo
的唯一情况.
执行此操作的正确方法是什么?
实例和 class 属性的变量注释中使用的信息存储在 class 上的 __annotations__
映射中,这是一个可写的字典。
如果您想添加到存储在那里的信息,那么只需将您的新信息直接添加到该映射:
A.__annotations__['bar'] = float
A.bar: float
注释被 Python 丢弃 ,因为没有专门的位置来存储 annotated expressions 的信息;由静态类型检查器实现来决定该表达式是否有意义。
参见 PEP 526 的 Runtime Effects of Type Annotations section -- 变量注释的语法,定义此语法的文档:
In addition, 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.
以及来自 Python 参考文档的 Annotated assignment statements section:
For simple names as assignment targets, if in class or module scope, the annotations are evaluated and stored in a special class or module attribute
__annotations__
that is a dictionary mapping from variable names (mangled if private) to evaluated annotations. This attribute is writable and is automatically created at the start of class or module body execution, if annotations are found statically.
A.bar
不是简单的名字,是表达式,所以不存储;如果您想在 __annotations__
映射中保留该信息以供运行时访问,那么手动设置它是唯一的选择。