我正在使用pytype(2019.10.17,最新版本)作为我的代码类型检查器来开发一个工具,该工具能够使用索引文件随机读取msgpack文件,该文件记录了位置(偏移量在每个邮件的msgpack文件)(存储在msgpack中的值)。就消息类型的多样性而言,我使用typing.TypeVar
来实现泛型类型。 pytype与TypeVar一起使用时遇到问题。
Name: pytype
Version: 2019.10.17
Summary: Python type inferencer
Home-page: https://google.github.io/pytype
Author: None
Author-email: None
License: UNKNOWN
Location: /home/gaoyunpeng/miniconda3/envs/restore/lib/python3.6/site-packages
Requires: ninja, typed-ast, six, importlab, pyyaml, attrs
Required-by:
Python 3.6.4 :: Anaconda, Inc.
from typing import TypeVar
T = TypeVar('T')
def f(x: T):
print(x)
使用以下命令运行以上代码:pytype main2.py
:
Computing dependencies
Analyzing 1 sources with 0 local dependencies
ninja: Entering directory `/home/gaoyunpeng/workspace/.pytype'
[1/1] check main2
FAILED: /home/gaoyunpeng/workspace/.pytype/pyi/main2.pyi
pytype-single --imports_info /home/gaoyunpeng/workspace/.pytype/imports/main2.imports --module-name main2 -V 3.6 -o /home/gaoyunpeng/workspace/.pytype/pyi/main2.pyi --analyze-annotated --nofail --quick /home/gaoyunp
eng/workspace/main2.py
File "/home/gaoyunpeng/workspace/main2.py", line 4, in <module>: Invalid type annotation 'T' [invalid-annotation]
Appears only once in the signature
For more details, see https://google.github.io/pytype/errors.html#invalid-annotation.
ninja: build stopped: subcommand failed.
如https://google.github.io/pytype/errors.html#invalid-annotation
所述,这种情况是无效的注释。
我想知道为什么代码无法通过pytype检查。
答案 0 :(得分:0)
打印出来的错误消息解释了为什么这是类型错误。如程序所示。引用错误消息的相关内容:
File "/home/gaoyunpeng/workspace/main2.py", line 4, in <module>: Invalid type annotation 'T' [invalid-annotation]
Appears only once in the signature
在给定的签名中仅使用TypeVar一次是错误的,因为这样做毫无意义。就您而言,您最好只使用类型签名def f(x: object) -> None
。您想说f
可以接受任何内容,Python中的所有内容都是object
的子类型。
仅当您要坚持两个或更多类型完全相同时,才应使用通用类型。例如,如果要定义“身份”函数,则使用泛型类型是正确的:
def identity(x: T) -> T:
return x
这将允许类型检查器推断identity("foo")
和identity(4)
分别为str和int类型-返回类型始终与参数类型相同。
请注意,对于一般类中的方法,此“每个签名应始终使用TypeVar两次或多次”规则同样适用。当您这样做时:
class Foo(Generic[T]):
def test(self, x: T) -> None: pass
... test
的签名实际上是def test(self: Foo[T], x: T) -> None
。因此,我们在那里也隐式总是使用TypeVar两次。