本地修补缺失的 Python 类型注释?

kdb*_*kdb 5 python static-typing mypy typeshed

Python 现在支持类型提示,所以...耶!这似乎是避免一些更隐蔽的运行时错误的好方法。

遗憾的是,第三方库支持仍然是一个问题。虽然typeshed项目(也由mypy使用)部分解决了这个问题,但当尝试移植我的一些代码以使用类型提示时,我遇到了由于缺少存根而遇到的问题。

例如

# file:mypytest.py
import lxml.etree as et
tree = et.fromstring('<root><a>1</a><b>2</b><a>3</a></root>')
items = tree.xpath('/root/a')
print([i.text for i in items])
Run Code Online (Sandbox Code Playgroud)

会工作得很好,但 mypy 会产生虚假的错误消息

>>> mypy mypytest.py
mypytest.py:3: error: "_Element" has no attribute "xpath"
Run Code Online (Sandbox Code Playgroud)

因为存根目前不完整。

对于较大的项目,从 typeshed 下载存根、添加缺少的条目,甚至提交相应的拉取请求都是理所当然的事情。

但是有没有某种方法可以在快速而肮脏的场景中对丢失的信息进行猴子修补呢?

不好的解决方法

我能想到的最好的办法是

items = tree.xpath('/root/a') # type: ignore
Run Code Online (Sandbox Code Playgroud)

这会消除错误,但也会禁用items随后使用变量的类型检查。例如items[0] + 1不会再引起警告。

为了保留类型检查,可以使用

items_tmp = tree.xpath('/root/a') # type: ignore
items = items_tmp # type: List[et._Element]
Run Code Online (Sandbox Code Playgroud)

但这似乎有些骇人听闻;.xpath在使用该方法的所有地方都必须重复该操作。

2017-09-12 更新:或者可以使用以下语法

items_tmp : List[et._Element] = tree.xpath('/root/a') # type: ignore
Run Code Online (Sandbox Code Playgroud)