Python中的类型提示(下)

Python中的类型提示(下)

当你碰壁时

总而言之,要小心了,类型提示有时会产生奇怪的警告,这会让人产生不好的感觉,就如这篇推特所总结的一样:

Python中的类型提示(下)

记住,在你的手头就有一些工具可以帮助你发现、理解和处理这些边缘情况;

· 使用reveal_type来看推理的类型:

Python中的类型提示(下)

· 使用cast来强制一个给定的类型:

Python中的类型提示(下)

· 使用类型忽略标记来禁用行中的错误:

Python中的类型提示(下)

· 在论坛中提问;在python/typing的Gittter chat下提供一个可以暴露出问题的最简洁的可复现版本。

工具

这里有一份关于类型提示系统的不是很详尽的工具列表。

类型检查器

使用这些工具在你的库或者应用中检查类型是否正确:

1、mypy – Python(之前提到的类型linter工具)

2、pyre – Facebook –仅针对python3,但是比mypy的运行速度快。一个有趣的用例是使用这个工具来进行污染/安全代码的分析。参见Pieter Hooimeijer - Types, Deeper Static Analysis, and you.

3、pytype - Google.

类型标注生成器

当你想要对一个已存的代码库添加类型标注,使用这些来自动进行这个枯燥的部分:

1、mypy stubgen命令行

2、pyannotate – Dropbox –使用你的运行结果来生成类型信息。

3、monkeytype – Instagram。有趣的是,instagram实际上使用这个工具在自己的产品系统中运行:每一百万次调用就触发一次(这个工具使得代码运行速度变慢了5倍,但一百万次才触发一次就不那么明显了)。

运行态的代码鉴别器

使用这些工具来在运行时检测输入到你的函数或方法的参数的格式是否正确:

1、pydantic

2、enforce

3、pytypes

文档增强-合并文档字符串和类型提示

在这篇长文的第一部分,我们提到了以前人们就是将类型信息存储在文档字符串中。之所以这么做的原因是类型数据也是你工作的一部分,你确实希望将库的类型信息放入文档中去。那么问题来了,你没有选择使用文档字符串作为类型信息的主要存储系统,如何将这些信息保存在文档字符串中呢?

这个答案取决于你用来生成文档的工具。在这里我将展示一种可选的方法,使用的工具是在python中最流行的工具和格式:Sphinx和HTML。

在类型提示和文档字符串中都声明类型信息最终一定会导致二者的冲突。你可以想象的到一个人同一时刻只能在一个地方更新信息。因此,让我们从文档字符串中删除所有的类型数据,仅从类型提示中获取。现在我们需要做的是在创建文档是时从类型提示中获取类型信息并加入到文档中去。

在Sphinx中,你可以通过一个插件来实现这样的操作。目前最流行的版本是agronholm/sphinx-autodoc-typehints。这个工具可以做两件事:

· 首先,针对要记录的每个函数或变量,它获取类型提示信息;

· 然后,将这些信息用文档字符串表示(这涉及到递归地展开所以嵌套的类型类,并用相应的字符串表示进行替换);

· 最后,将正确的参数附加进文档字符串中去。

举个例子,Any映射的类型是py:data:`~typing.Any`。对于组合类型来说会变得更加复杂,比如Mapping[str, bool]需要被翻译成形如:class:`~typing.Mapping`\[:class:`str`, :class:`bool`]的字符串。正确的翻译(例如类或者数据的名称)对于intersphinx插件能够正确的工作是至关重要的(一个能够将类型直接链接到他们各自的python标准库文档的插件)。

为了使用这个工具,我们需要通过pip install sphinx-autodoc-type>=2.1.1来安装,然后在conf.py文件中启用:

Python中的类型提示(下)

这样就可以了。这里以RookieGameDevs/revived的文档作为例子。比如给出如下的源代码:

Python中的类型提示(下)

你可以得到这样的输出:

Python中的类型提示(下)

结论

这里就是这篇长文的结尾了,你或许想问:类型提示是否值得使用,或者应该什么时候使用。我认为类型提示和在一天的工作收尾时进行的单元测试在性质上是一样的,只是代码的表达方式不同。它们都提供了一种标准的(可复用的)方法来测试你代码库输入输出的类型。

正因如此,当值得编写单元测试的时候,都应该使用类型提示。就算是以后需要维护的情况下,也只需要10行代码就够了。同样,你还应该在你开始编写单元测试的同时开始添加类型提示。我只在不需要单元测试的地方或者一次性的脚本上才不考虑添加类型提示。

记住,与单元测试类似,虽然它会使你的代码库中额外多出一些代码。但是完成这项工作后,所有你添加的代码都是用来自动检查并确保其他部分的正确性的。它就像安全网一样,确保当你在以后做出修改时程序可以继续工作,所以为此付出额外的代价应该是值得的。

Python中的类型提示(下)
英文原文:https://www.bernat.tech/the-state-of-type-hints-in-python/
译者:舞象加冠


分享到:


相關文章: