5

我正在尝试在当前项目中实现类型注释,并且从 mypy 收到我不理解的错误。

我正在使用 Python 2.7.11,并在我的基本 virtualenv 中新安装了 mypy。以下程序运行良好:

from __future__ import print_function
from types import StringTypes
from typing import List, Union, Callable

def f(value):     # type: (StringTypes) -> StringTypes
    return value

if __name__ == '__main__':
    print("{}".format(f('some text')))
    print("{}".format(f(u'some unicode text')))

但运行mypy --py2 -s mypy_issue.py返回以下内容:

mypy_issue.py: note: In function "f":
mypy_issue.py:8: error: Invalid type "types.StringTypes"

上述类型似乎在Typeshed ... mypy文档中说“Mypy 合并了 typeshed 项目,其中包含 Python 内置函数和标准库的库存根。” ...不确定“合并”是什么意思 - 我需要做一些事情来“激活”或提供通往 Typeshed 的路径?我需要在本地下载和安装(?)Typeshed 吗?

4

1 回答 1

7

问题在于它types.StringTypes被定义为一系列类型——Typeshed 上的正式类型签名是:

StringTypes = (StringType, UnicodeType)

这对应于官方文档,其中指出该StringTypes常量是“包含StringType和的序列UnicodeType”...

那么,这就解释了你得到的错误——StringTypes它不是一个实际的类(它可能是一个元组),所以 mypy 不能把它识别为一个有效的类型。

有几个可能的解决方法。

第一种方法可能是使用typing.AnyStrwhich is defined as AnyStr = TypeVar('AnyStr', bytes, unicode)。尽管AnyStr包含在模块中,但不幸的是,到目前为止,它的文档记录有些差——您可以在 mypy 文档typing中找到有关它的功能的更多详细信息。

一种稍微不那么干净的表达方式是:

from types import StringType, UnicodeType
from typing import Union

MyStringTypes = Union[StringType, UnicodeType]

def f(value):     
    # type: (MyStringTypes) -> MyStringTypes
    return value

这也有效,但不太理想,因为返回类型不再必须与输入类型相同,这在处理不同类型的字符串时通常不是您想要的。

至于 typeshed——安装 mypy 时默认捆绑了它。在理想的世界中,您根本不需要担心 typeshed,但由于 mypy 处于 beta 阶段,因此 typeshed 经常更新以解决丢失的模块或不正确的类型注释,因此可能值得直接从Github安装 mypy如果您发现自己经常遇到 typeshed 的错误,请在本地repo并安装 typeshed。

于 2016-08-08T22:56:13.603 回答