Python类型提示语法如何/为什么起作用? [英] How / why does Python type hinting syntax work?

查看:192
本文介绍了Python类型提示语法如何/为什么起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚在中看到了以下示例PEP 484 :

def greeting(name: str) -> str:
    return 'Hello ' + name

print(greeting('Martin'))
print(greeting(1))

按预期,这在Python 2中无效:

As expected, this does not work in Python 2:

  File "test.py", line 1
    def greeting(name: str) -> str:
                     ^
SyntaxError: invalid syntax

但是,它适用于Python 3:

However, it works for 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

这是意外的.如下面的示例所示,它还没有真正检查类型(它可以运行,但不会引发异常):

This was unexpected. It does not really check types yet, as you can see with the following example (it runs, but does not throw an exception):

def greeting(name: str) -> int:
    return 'Hello ' + name

print(greeting('Martin'))

似乎在:之后必须是一个函数的名称,但是该函数似乎被忽略了:

It seems as if after the : has to be the name of a function, but the function seems to be ignored:

def aha(something):
    print("aha")
    return something+"!"

def greeting(name: aha, foo) -> int:
    return 'Hello ' + name + foo

print(greeting('Martin', 'ad'))

->之后的名称似乎也是如此.

The same seems to be true for the name after ->.

此类型提示语法是否还使用了其他内容(例如Java Modeling语言使用了注释)?何时将此语法引入Python?有没有一种方法可以使用此语法进行静态类型检查?它是否总是破坏Python 2的兼容性?

Is this type hinting syntax using something else (like Java Modeling language makes use of comments)? When was this syntax introduced to Python? Is there a way to do static type checking already with this Syntax? Does it always break Python 2 compatibility?

推荐答案

此处没有类型提示.您所做的只是提供注释;这些是通过 PEP 3107 引入的(仅在Python 3中,在Python 2中不支持此功能) );它们使您可以注释参数并使用任意信息返回值以供以后检查:

There is no type hinting going on here. All you did was provide annotations; these were introduced with PEP 3107 (only in Python 3, there is no support for this in Python 2); they let you annotate arguments and return values with arbitrary information for later inspection:

>>> greeting.__annotations__
{'name': <class 'str'>, 'return': <class 'str'>}

否则,这里完全不咨询他们.相反,您收到的错误消息是试图在函数主体中串联字符串和整数值 :

They are otherwise not consulted at all here. Instead, the error message you got is from trying to concatenate string and integer values in the body of the function:

>>> '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的类型,它由str.__add__方法抛出:

It is a custom type error aimed at providing additional information as to why the str + int concatenation failed; it is thrown by the str.__add__ method for any type that is not 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状态的介绍:

PEP 484 then proposes to make use of those annotations to do actual static type checking with additional tools, but as the introduction of the PEP states:

尽管这些注释可以在运行时通过常规的__annotations__属性使用,但在运行时不会进行类型检查.相反,该建议假定存在一个单独的脱机类型检查器,用户可以自动在其源代码上运行该检查器.本质上,这样的类型检查器可以充当非常强大的linter.

While these annotations are available at runtime through the usual __annotations__ attribute, no type checking happens at runtime. Instead, the proposal assumes the existence of a separate off-line type checker which users can run over their source code voluntarily. Essentially, such a type checker acts as a very powerful linter.

强调原始内容.

PEP受到使用PEP 3107注释的现有工具的启发;尤其是 mypy项目(通过采用PEP 484循环返回),还包括PyCharm IDE中的类型提示支持开始这项工作的原始电子邮件以及后续电子邮件.

The PEP was inspired by existing tools that use PEP 3107 annotations; specifically the mypy project (which is looping right back by adopting PEP 484), but also the type hinting support in the PyCharm IDE and the pytypedecl project. See Guido van Rossum's original email kickstarting this effort as well as a follow-up email.

mypy显然可以通过预处理注释来支持Python 2,在为您字节编译源代码之前先将其删除,但否则您通常无法使用旨在在Python 2中工作的Python语法.

mypy apparently supports Python 2 by preprocessing the annotations, removing them before byte-compiling the source code for you, but you otherwise cannot normally use the syntax Python code meant to work in Python 2.

PEP 484还描述了存根文件的使用,常规的Python文件;它们使用.pyi扩展名,并且仅包含签名(带有类型提示),而使主要的.py文件注释自由,因此可以在Python 2上使用(前提是您另外编写了Polyglot Python代码).

PEP 484 also describes the use of stub files, which sit next to the regular Python files; these use the .pyi extension and only contain the signatures (with type hints), leaving the main .py files annotation free and thus usable on Python 2 (provided you wrote Polyglot Python code otherwise).

这篇关于Python类型提示语法如何/为什么起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆