使用 mypy 在 Python 中检查类型注解

了解更多关于在我们涵盖七个 PyPI 库的系列文章中解决常见 Python 问题的信息。
131 位读者喜欢这篇文章。
How to find files in Linux

Lewis Cowles, CC BY-SA 4.0

Python 是当今使用最流行的编程语言之一,这是有充分理由的:它是开源的,它具有广泛的用途(例如 Web 编程、商业应用程序、游戏、科学编程等等),并且它拥有一个充满活力和敬业的社区来支持它。正是由于这个社区,我们才能在 Python 包索引 (PyPI) 中获得如此庞大、多样化的软件包,以扩展和改进 Python 并解决不可避免出现的小故障。

在本系列中,我们研究了七个 PyPI 库,它们可以帮助您解决常见的 Python 问题。今天,在最后一篇文章中,我们将看看 mypy,“Python 超级 Linter”。

mypy

Python 是一种“动态类型”语言。 但是,有时让其他主体(包括机器人和人类)知道期望的类型会很好。 传统上,人类的优先级更高:函数的输入和输出类型在文档字符串中进行了描述。 MyPy 允许您将机器人置于同等地位,让他们知道预期的类型。

让我们看看下面的代码

def add_one(input):
    return input + 1

def print_seven():
    five = "5"
    seven = add_one(add_one(five))
    print(seven)

调用 print_seven 会引发 TypeError,告知我们无法将字符串和数字相加:我们无法将“5”和 1 相加。

但是,我们只有在运行代码后才能知道这一点。 如果代码正确,运行代码会在屏幕上生成打印输出:一种副作用。 从副作用来看,这是一种相对无害的副作用,但仍然是一种副作用。 有可能在不冒任何副作用的风险的情况下做到这一点吗?

我们只需要让机器人知道会发生什么。

def add_one(input: int) -> int:
    return input + 1

def print_seven() -> None:
    five = "5"
    seven = add_one(add_one(five))
    print(seven)

我们使用类型注解来表示 add_one 期望一个整数并返回一个整数。 这不会改变代码的作用。 但是,现在我们可以要求一个安全的机器人来为我们找到问题。

$ mypy typed.py 
typed.py:6: error: Argument 1 to "add_one" has incompatible type "str"; expected "int"

我们对我们做错的事情有一个清晰易懂的解释。 让我们修复 print_seven

def print_seven() -> None:
    five = 5
    seven = add_one(add_one(five))
    print(seven)

如果我们在上面运行 mypy,就不会有任何抱怨;我们修复了错误。 令人高兴的是,这也导致了可以正常工作的代码。

当然,Python 类型系统可能会非常深入。 遇到类似这样的签名并不罕见

from typing import Dict, List, Mapping, Sequence

def unify_results(
    results1: Mapping[str, Sequence[int]],
    results2: Mapping[str, Sequence[int]]
) -> Dict[str, List[int]]:
    pass

在这些情况下,请记住一切都是对象:是的,甚至是类型。

ResultsType = Mapping[str, Sequence[int]]
ConcreteResultsType = Dict[str, List[int]]

def unify_results(results1: ResultsType, results2: ResultsType) -> ConcreteResultsType:
    pass

我们将输入类型定义为抽象类型(使用 MappingSequence)。 这允许传入,例如,将字符串映射到元组的 defaultdict。 这通常是正确的选择。 我们还选择在签名中保证具体的返回类型。 这更具争议性:有时,为了允许将来更改返回类型,保证更少的东西是有用的。

MyPy 允许渐进式注解:不必一次注解所有内容。 没有任何注解的函数将不会进行类型检查。

前进并注解吧!

回顾本系列之前的文章

标签
Moshe sitting down, head slightly to the side. His t-shirt has Guardians of the Galaxy silhoutes against a background of sound visualization bars.
Moshe 自 1998 年以来一直参与 Linux 社区,在 Linux“安装派对”中提供帮助。 他自 1999 年以来一直使用 Python 编程,并为核心 Python 解释器做出了贡献。 Moshe 自从这些术语出现之前就一直是 DevOps/SRE,非常关心软件的可靠性、构建的可重复性以及其他此类事情。

评论已关闭。

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.