Python 3.6 中的变量注释是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39971929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are variable annotations in Python 3.6?
提问by fedorqui 'SO stop harming'
Python 3.6 is about to be released. PEP 494 -- Python 3.6 Release Schedulementions the end of December, so I went through What's New in Python 3.6to see they mention the variable annotations:
Python 3.6 即将发布。PEP 494 -- Python 3.6 发布时间表提到了 12 月底,所以我浏览了 Python 3.6 中的新增功能,看看他们提到了变量注释:
PEP 484introduced standard for type annotations of function parameters, a.k.a. type hints. This PEP adds syntax to Python for annotating the types of variables including class variables and instance variables:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: Dict[str, int] = {}
Just as for function annotations, the Python interpreter does not attach any particular meaning to variable annotations and only stores them in a special attribute
__annotations__
of a class or module. In contrast to variable declarations in statically typed languages, the goal of annotation syntax is to provide an easy way to specify structured type metadata for third party tools and libraries via the abstract syntax tree and the__annotations__
attribute.
PEP 484引入了函数参数类型注释的标准,也就是类型提示。此 PEP 向 Python 添加了用于注释变量类型(包括类变量和实例变量)的语法:
primes: List[int] = [] captain: str # Note: no initial value! class Starship: stats: Dict[str, int] = {}
就像函数注解一样,Python 解释器没有给变量注解附加任何特定的含义,只将它们存储在
__annotations__
类或模块的特殊属性中。与静态类型语言中的变量声明相比,注释语法的目标是提供一种简单的方法,通过抽象语法树和__annotations__
属性为第三方工具和库指定结构化类型元数据。
So from what I read they are part of the type hints coming from Python 3.5, described in What are Type hints in Python 3.5.
因此,从我读到的内容来看,它们是来自 Python 3.5 的类型提示的一部分,在 Python 3.5中的类型提示是什么中进行了描述。
I follow the captain: str
and class Starship
example, but not sure about the last one: How does primes: List[int] = []
explain? Is it defining an empty list that will just allow integers?
我遵循captain: str
和class Starship
示例,但不确定最后一个:如何primes: List[int] = []
解释?它是否定义了一个只允许整数的空列表?
采纳答案by Martijn Pieters
Everything between :
and the =
is a type hint, so primes
is indeed defined as List[int]
, and initially set to an empty list (and stats
is an empty dictionary initially, defined as Dict[str, int]
).
:
和之间的所有内容都是=
类型提示,因此primes
确实定义为List[int]
,并且最初设置为一个空列表(并且stats
最初是一个空字典,定义为Dict[str, int]
)。
List[int]
and Dict[str, int]
are not part of the next syntax however, these were already defined in the Python 3.5 typing hints PEP. The 3.6 PEP 526 – Syntax for Variable Annotationsproposal onlydefines the syntax to attach the same hints to variables; before you could only attach type hints to variables with comments (e.g. primes = [] # List[int]
).
List[int]
并且Dict[str, int]
不是下一个语法的一部分,但是,这些已经在 Python 3.5 类型提示 PEP 中定义。3.6 PEP 526 –变量注释的语法提案仅定义了将相同提示附加到变量的语法;在您只能将类型提示附加到带有注释的变量之前(例如primes = [] # List[int]
)。
Both List
and Dict
are Generictypes, indicating that you have a list or dictionary mapping with specific (concrete) contents.
这两个List
和Dict
是通用类型,这表明你有特定的(具体)内容的列表或字典映射。
For List
, there is only one 'argument' (the elements in the [...]
syntax), the type of every element in the list. For Dict
, the first argument is the key type, and the second the value type. So allvalues in the primes
list are integers, and allkey-value pairs in the stats
dictionary are (str, int)
pairs, mapping strings to integers.
对于List
,只有一个“参数”([...]
语法中的元素),即列表中每个元素的类型。对于Dict
,第一个参数是键类型,第二个参数是值类型。所以列表中的所有值primes
都是整数,字典中的所有键值对stats
都是(str, int)
成对的,将字符串映射到整数。
See the typing.List
and typing.Dict
definitions, the section on Generics, as well as PEP 483 – The Theory of Type Hints.
请参阅typing.List
和typing.Dict
定义、泛型部分以及PEP 483 –类型提示理论。
Like type hints on functions, their use is optional and are also considered annotations(provided there is an object to attach these to, so globals in modules and attributes on classes, but not locals in functions) which you could introspect via the __annotations__
attribute. You can attach arbitrary info to these annotations, you are not strictly limited to type hint information.
就像函数的类型提示一样,它们的使用是可选的,也被认为是注释(如果有一个对象可以将它们附加到,那么模块中的全局变量和类的属性,而不是函数中的局部变量),您可以通过__annotations__
属性内省。您可以将任意信息附加到这些注释中,您并不仅限于键入提示信息。
You may want to read the full proposal; it contains some additional functionality above and beyond the new syntax; it specifies when such annotations are evaluated, how to introspect them and how to declare something as a class attribute vs. instance attribute, for example.
您可能想阅读完整的提案;它包含一些超出新语法的附加功能;例如,它指定何时评估此类注释,如何内省它们以及如何将某些内容声明为类属性与实例属性。
回答by Dimitris Fasarakis Hilliard
What are variable annotations?
什么是变量注解?
Variable annotations are just the next step from # type
comments, as they were defined in PEP 484
; the rationale behind this change is highlighted in the respective section of PEP 526.
变量注释只是注释的下一步# type
,因为它们在PEP 484
; PEP 526的相应部分强调了这一变化背后的基本原理。
So, instead of hinting the type with:
因此,不要用以下方式暗示类型:
primes = [] # type: List[int]
New syntax was introducedto allow for directly annotating the type with an assignment of the form:
引入了新语法以允许使用表单赋值直接注释类型:
primes: List[int] = []
which, as @Martijn pointed out, denotes a list of integers by using types available in typing
and initializing it to an empty list.
正如@Martijn 指出的那样,typing
它通过使用中可用的类型并将其初始化为空列表来表示整数列表。
What changes does it bring?
它带来了哪些变化?
The first change introduced was new syntaxthat allows you to annotate a name with a type, either standalone after the :
character or optionally annotate while also assigning a value to it:
引入的第一个更改是新语法,它允许您使用类型注释名称,可以在:
字符后独立,也可以选择注释同时为其分配值:
annotated_assignment_stmt ::= augtarget ":" expression ["=" expression]
So the example in question:
所以有问题的例子:
primes: List[int] = [ ]
# ^ ^ ^
# augtarget | |
# expression |
# expression (optionally initialize to empty list)
Additional changes were also introduced along with the new syntax; modules and classes now have an __annotations__
attribute (as functions have had since PEP 3107 -- Function Annotations) in which the type metadata is attached:
还引入了其他更改以及新语法;模块和类现在有一个__annotations__
属性(就像自PEP 3107以来的函数一样——函数注释),其中附加了类型元数据:
from typing import get_type_hints # grabs __annotations__
Now __main__.__annotations__
holds the declared types:
现在__main__.__annotations__
保存声明的类型:
>>> from typing import List, get_type_hints
>>> primes: List[int] = []
>>> captain: str
>>> import __main__
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int]}
captain
won't currently show up through get_type_hints
because get_type_hints
only returns types that can also be accessed on a module; i.e., it needs a value first:
captain
目前不会显示出来,get_type_hints
因为get_type_hints
只返回也可以在模块上访问的类型;即,它首先需要一个值:
>>> captain = "Picard"
>>> get_type_hints(__main__)
{'primes': typing.List<~T>[int], 'captain': <class 'str'>}
Using print(__annotations__)
will show 'captain': <class 'str'>
but you really shouldn't be accessing __annotations__
directly.
Using print(__annotations__)
will show'captain': <class 'str'>
但你真的不应该__annotations__
直接访问。
Similarly, for classes:
同样,对于类:
>>> get_type_hints(Starship)
ChainMap({'stats': typing.Dict<~KT, ~VT>[str, int]}, {})
Where a ChainMap
is used to grab the annotations for a given class (located in the first mapping) and all annotations defined in the base classes found in its mro
(consequent mappings, {}
for object).
其中 aChainMap
用于获取给定类(位于第一个映射中)的注释以及在其mro
(后续映射,{}
对象)中找到的基类中定义的所有注释。
Along with the new syntax, a new ClassVar
type has been added to denote class variables. Yup, stats
in your example is actually an instance variable, not a ClassVar
.
除了新语法,ClassVar
还添加了一个新类型来表示类变量。是的,stats
在您的示例中实际上是一个实例变量,而不是ClassVar
.
Will I be forced to use it?
我会被迫使用它吗?
As with type hints from PEP 484
, these are completely optionaland are of main use for type checking tools (and whatever else you can build based on this information). It is to be provisional when the stable version of Python 3.6 is released so small tweaks might be added in the future.
与来自 的类型提示一样PEP 484
,这些是完全可选的,主要用于类型检查工具(以及您可以基于此信息构建的任何其他工具)。当 Python 3.6 的稳定版本发布时它是临时的,因此将来可能会添加一些小的调整。