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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 23:00:50  来源:igfitidea点击:

What are variable annotations in Python 3.6?

pythonpython-3.xannotationstype-hintingpython-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: strand class Starshipexample, 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: strclass Starship示例,但不确定最后一个:如何primes: List[int] = []解释?它是否定义了一个只允许整数的空列表?

采纳答案by Martijn Pieters

Everything between :and the =is a type hint, so primesis indeed defined as List[int], and initially set to an empty list (and statsis 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 Listand Dictare Generictypes, indicating that you have a list or dictionary mapping with specific (concrete) contents.

这两个ListDict通用类型,这表明你有特定的(具体)内容的列表或字典映射。

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 primeslist are integers, and allkey-value pairs in the statsdictionary are (str, int)pairs, mapping strings to integers.

对于List,只有一个“参数”([...]语法中的元素),即列表中每个元素的类型。对于Dict,第一个参数是键类型,第二个参数是值类型。所以列表中的所有primes都是整数,字典中的所有键值对stats都是(str, int)成对的,将字符串映射到整数。

See the typing.Listand typing.Dictdefinitions, the section on Generics, as well as PEP 483 – The Theory of Type Hints.

请参阅typing.Listtyping.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 # typecomments, 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 typingand 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]}

captainwon't currently show up through get_type_hintsbecause get_type_hintsonly 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 ChainMapis 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 ClassVartype has been added to denote class variables. Yup, statsin 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 的稳定版本发布时它是临时的,因此将来可能会添加一些小的调整。