为什么在 python 3.5 + 中使用类型

Why to use types in python 3.5 +

我试图理解为什么我应该在 python 中使用类型注释。例如,我可以编写如下函数:

def some_function(a: int, b: int) -> int:
    return a + b

当我将它与 int 一起使用时,一切都很好:

some_function(1, 2)  # return 3, type int

但是当我 运行 例如

some_function(1, 2.0) # return 3.0, type float

我得到的结果没有任何类型错误的注释。那么使用类型注释的原因是什么?

其他工具 会提供类型提示来检查您的代码,它们不会在 运行 时强制执行。目标是使静态分析工具能够检测无效参数使用。

使用像 PyCharm 这样的 IDE 或 commandline code checker mypy 来告知 2.0 不是有效的参数类型。

来自Type Hinting PEP (484)

This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and (perhaps, in some contexts) code generation utilizing type information.

强调我的。运行时类型检查留给第三方工具。请注意,这种 运行 时间检查会带来性能下降,如果您要在每次调用时检查类型,您的代码可能会 运行 变慢。

正如人们在 PEP 484 中所读到的那样 that introduces type hints:

(...)

This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and (perhaps, in some contexts) code generation utilizing type information.

Of these goals, static analysis is the most important. This includes support for off-line type checkers such as mypy, as well as providing a standard notation that can be used by IDEs for code completion and refactoring.

IDE的(静态分析)

所以主要用在静态分析:你的IDE可以在你调用一个函数的时候检测出有问题,并且可以提供一个函数列表,你可以调用函数的结果。

例如,如果你写:

some_function(1,2).

你的 IDE 可以提供一个列表 real 作为一个可能的选项,这样你就可以轻松地写:

some_function(1,2).real

如果你写:

some_function('foo',2).bar

它会提示 'foo' 不是可接受的参数,.bar 也不是对该对象的良好调用。

动态检测

您还可以将其用于 inspect.getfulargspec 的动态检查,例如:

>>> import inspect
>>> inspect.getfullargspec(some_function).annotations
{'return': <class 'int'>, 'a': <class 'int'>, 'b': <class 'int'>}

现在我们知道 some_function returns 一个 int 并且可以喂两个 int。这可以用于 任意测试 (在 Haskell 中很流行):你只需输入 some_function 随机整数,看起来它总是 returns一个 int(例如不会引发异常)。