What are Type hints in Python 3.5
据说
本文中提到了
我建议阅读PEP 483和PEP 484,并观看guido关于类型暗示的演示。好的。
简而言之:类型暗示就是字面上的意思,你暗示了你正在使用的对象的类型。好的。
由于python的动态特性,推断或检查正在使用的对象的类型尤其困难。这一事实使得开发人员很难理解他们尚未编写的代码中到底发生了什么,最重要的是,对于许多IDES中的类型检查工具[PyCharm,PyDev想到的是],这些工具由于没有任何对象类型的指示器而受到限制。因此,他们尝试推断类型(如演示中提到的)成功率约为50%。好的。
从提示式演示文稿中选取两张重要幻灯片:好的。为什么输入提示?
为什么使用静态类型检查程序?
- 尽早发现虫子:我相信这是不言而喻的。
- 你的项目越大,你就越需要它:同样,这是有道理的。静态语言提供了一种健壮性和控制能力,动态语言缺乏。应用程序越大、越复杂,控制和可预测性就越强(从行为方面)你需要的。
- 大型团队已经在运行静态分析:我猜这会验证前两点。
作为这个小介绍的结束语:这是一个可选特性,据我所知,它是为了获得静态类型的一些好处而引入的。好的。
您通常不需要担心它,也绝对不需要使用它(特别是在您将Python用作辅助脚本语言的情况下)。在开发大型项目时,它应该是有用的,因为它提供了非常需要的健壮性、控制和额外的调试功能。好的。用mypy提示:
为了使这个答案更完整,我认为进行一点演示是合适的。我将使用
在此之前,让我重申以下几点:PEP 484不强制执行任何操作;它只是为函数设置一个方向。注释和建议如何执行类型检查的指南。您可以注释您的函数和提示尽可能多的东西;您的脚本仍然可以运行,而不考虑注释的存在,因为Python本身不使用它们。好的。
无论如何,正如政治公众人物所指出的,暗示类型通常应采取三种形式:好的。
- 函数注释。(PEP 3107)
- 内置/用户模块的存根文件。
- 补充前两种形式的特殊
# type: type 注释。(请参见:Python3.6中的变量注释是什么?对于用于# type: type 注释的python 3.6更新)
此外,您还需要将类型提示与
对于任何想更深入地解释这些问题的人来说,
首先,在使用特殊注释时观察一些我们可以得到的行为是很有趣的。
注:如果我们想要使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # generic List, supports indexing. from typing import List # In this case, the type is easily inferred as type: int. i = 0 # Even though the type can be inferred as of type list # there is no way to know the contents of this list. # By using type: List[str] we indicate we want to use a list of strings. a = [] # type: List[str] # Appending an int to our list # is statically not correct. a.append(i) # Appending a string is fine. a.append("i") print(a) # [0, 'i'] |
如果我们将这些命令添加到一个文件中,并用我们的解释器执行它们,一切都会正常工作,
另一方面,通过与
1 2 | (Python3)jimmi@jim: mypy typeHintsCode.py typesInline.py:14: error: Argument 1 to"append" of"list" has incompatible type"int"; expected"str" |
号
说明
函数注释以
1 2 | def annotated(x: int, y: str) -> bool: return x < y |
1 | {'y': <class 'str'>, 'return': <class 'bool'>, 'x': <class 'int'>} |
号
如果我们是一个彻头彻尾的笨蛋,或者我们熟悉
1 2 3 | (Python3)jimmi@jim: mypy typeHintsCode.py typeFunction.py: note: In function"annotated": typeFunction.py:2: error: Unsupported operand types for > ("str" and"int") |
除此之外,使用无效参数调用函数也会被捕获:好的。
1 2 3 4 | annotated(20, 20) # mypy complains: typeHintsCode.py:4: error: Argument 2 to"annotated" has incompatible type"int"; expected"str" |
。
这些可以扩展到基本上任何用例,捕获的错误扩展到基本调用和操作之外。你的类型可以检查的真的很灵活,我只是给了它一个小的潜入峰值的潜力。在
存根文件可用于两种不同的非互斥情况:好的。
- 您需要对不想直接更改函数签名的模块进行类型检查。
- 您希望编写模块并进行类型检查,但还希望将注释与内容分开。
存根文件(扩展名为
1 2 3 4 5 6 7 8 9 10 | def message(s): print(s) def alterContents(myIterable): return [i for i in myIterable if i % 2 == 0] def combine(messageFunc, itFunc): messageFunc("Printing the Iterable") a = alterContents(range(1, 20)) return set(a) |
我们可以创建一个存根文件
无论如何,存根文件的结构相当简单:添加所有的函数定义,并填充空的主体(
1 2 3 4 5 6 7 8 9 10 11 | # Stub for randfucn.py from typing import Iterable, List, Set, Callable def message(s: str) -> None: pass def alterContents(myIterable: Iterable[int])-> List[int]: pass def combine( messageFunc: Callable[[str], Any], itFunc: Callable[[Iterable[int]], List[int]] )-> Set[int]: pass |
。
这将使您熟悉Python中类型提示的基本概念。即使使用的类型检查器
我知道的跳棋:好的。
- MYPY:如本文所述。
- Pytype:在谷歌,使用的符号和我收集到的不同,可能值得一看。
相关包/项目:好的。
- 排版:官方python repo为标准库提供各种存根文件。
1 2 3 4 5 6 7 | class Counter(Dict[_T, int], Generic[_T]): @overload def __init__(self) -> None: ... @overload def __init__(self, Mapping: Mapping[_T, int]) -> None: ... @overload def __init__(self, iterable: Iterable[_T]) -> None: ... |
其中,
注意:我忘记提到的一件事是,
A provisional package may have its API modified prior to"graduating" into a"stable" state. On one hand, this state provides the package with the benefits of being formally part of the Python distribution. On the other hand, the core development team explicitly states that no promises are made with regards to the the stability of the package's API, which may change for the next release. While it is considered an unlikely outcome, such packages may even be removed from the standard library without a deprecation period if the concerns regarding their API or maintenance prove well-founded.
Ok.
号
所以在这里拿点盐来;我怀疑它会被移除或以重要的方式改变,但人们永远不知道。好的。
**另一个主题在类型提示范围内完全有效:
在python 3.6中看到什么是变量注释?如前所述,为这些小介绍。好的。好啊。
在吉姆详细回答的基础上:
检查
例如,下面的函数接受并返回
1 2 | def greeting(name: str) -> str: return 'Hello ' + name |
新发布的pycharm 5支持类型暗示。在他们关于它的博客文章中(参见pycharm 5中的python 3.5类型暗示),他们提供了一个关于什么是类型提示的很好的解释,并没有提供一些示例和插图来说明如何在代码中使用它们。
另外,在python 2.7中也支持它,如本文中所述:
PyCharm supports the typing module from PyPI for Python 2.7, Python 3.2-3.4. For 2.7 you have to put type hints in *.pyi stub files since function annotations were added in Python 3.0.
号