我刚看到PEP 484中的以下示例:
def greeting(name: str) -> str:
return 'Hello ' + name
print(greeting('Martin'))
print(greeting(1))
正如所料,这在Python 2中不起作用:
File "test.py", line 1
def greeting(name: str) -> str:
^
SyntaxError: invalid syntax
但是,它适用于Python 3:
Hello Martin
Traceback (most recent call last):
File "test.py", line 5, in <module>
print(greeting(1))
File "test.py", line 2, in greeting
return 'Hello ' + name
TypeError: Can't convert 'int' object to str implicitly
这是出乎意料的。它还没有真正检查类型,你可以看到以下示例(它运行,但不会抛出异常):
def greeting(name: str) -> int:
return 'Hello ' + name
print(greeting('Martin'))
似乎在:
之后必须是函数的名称,但函数似乎被忽略了:
def aha(something):
print("aha")
return something+"!"
def greeting(name: aha, foo) -> int:
return 'Hello ' + name + foo
print(greeting('Martin', 'ad'))
->
之后的名称似乎也是如此。
这种类型的提示语法是否使用了其他东西(比如Java Modeling语言使用了注释)?这个语法是什么时候引入Python的?有没有办法用这个语法进行静态类型检查?它总是会破坏Python 2的兼容性吗?
答案 0 :(得分:29)
此处没有类型提示。你所做的只是提供注释;这些是PEP 3107引入的(仅在Python 3中,Python 2中不支持这种情况);它们允许您注释参数并使用任意信息返回值以供以后检查:
>>> greeting.__annotations__
{'name': <class 'str'>, 'return': <class 'str'>}
在这里,他们根本没有被咨询过。相反,您得到的错误消息是尝试在函数体中连接字符串和整数值 :
>>> 'Hello ' + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
这是一个自定义类型错误,旨在提供有关str
+ int
连接失败的原因的其他信息;对于任何非str.__add__
的类型,str
方法都会抛出它:
>>> ''.__add__(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
>>> ''.__add__(True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'bool' object to str implicitly
然后,PEP 484建议使用这些注释来使用附加工具进行实际的静态类型检查,但是随着PEP的引入说明:
虽然这些注释在运行时通过通常的
__annotations__
属性可用,但在运行时没有进行类型检查。相反,该提议假定存在一个单独的离线类型检查器,用户可以自动运行其源代码。从本质上讲,这种类型的检查器就像一个非常强大的linter。
强调原作。
PEP的灵感来自使用PEP 3107注释的现有工具;特别是mypy project(通过采用PEP 484循环回来),还有type hinting support in the PyCharm IDE和pytypedecl project。见Guido van Rossum的original email kickstarting this effort以及follow-up email。
mypy通过预处理注释显然支持Python 2,在为您编译源代码之前删除它们,但是否则通常不能使用Python代码在Python 2中工作的语法。
PEP 484还描述了stub files的使用,它位于常规Python文件的旁边;这些使用.pyi
扩展名,只包含签名(带有类型提示),保留主.py
个文件注释,因此可以在Python 2上使用(前提是你编写了Polyglot Python代码)。