Python 中的类型注释是否强制执行静态类型检查?

1 python static-typing typechecking

我正在尝试使用typing模块在用 Python 编写的项目中强制执行一些静态类型检查。

当我定义一个类似于文档中的函数时

def greeting(name: str) -> str:
    return 'Hello ' + name
Run Code Online (Sandbox Code Playgroud)

并尝试做类似的事情greeting(3),我确实收到了以下错误

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in greeting
TypeError: must be str, not int
Run Code Online (Sandbox Code Playgroud)

但是当我再次定义一个名为 test

def test(a: int) -> None:
    print(a)
Run Code Online (Sandbox Code Playgroud)

并且做test("a"),我已经a打印了,没有出现任何错误。我也试过

def test(a: str) -> None:
    print(a)
Run Code Online (Sandbox Code Playgroud)

和 do test(3),但没有引发 TypeError 。

我在完全相同的环境中定义了这两个函数,即使用 iTerm 的交互 python 会话。为什么会发生这种情况?

Don*_*Mee 5

python 中的类型注释强制执行静态类型检查。

Python 仍然是一种动态语言,其中解释器检查它是否有一个方法来执行操作,当它在执行循环期间到达这一行时,添加一个 str(“hello”)并添加一个整数(3)。Pep-484声明核心开发人员不想用注释来改变这一点。

如果您查看文档,它被称为'type hints'。提示不是强制执行。

类型提示实际上是供开发人员及其工具(如 IDE)更好地记录参数的预期类型。但是添加这种形式的文档不会对论点施加任何限制。它只是文档。实际上,最好将这些注释视为文档

您看到的错误发生在没有这些注释的情况下。例如

>>> "Hello" + 3
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以开发工具来执行此操作。对象上的注释

__annotations__
Run Code Online (Sandbox Code Playgroud)

为什么会这样? 在python中,我们一般不做显式的类型检查。相反,我们只是尝试调用该方法,例如“添加 'hello' 和 3”,然后出现错误。由函数的调用者提供正确的类型。但这也意味着由函数的作者来准确记录参数。类型提示有助于描述预期的类型,并使其在对象上可用,这对于其他工具然后挂钩很有用。以前,我们会将这些东西写成文档,例如:

def greeting(name):
    """Greeting to name
    :param name: str, the name to greet
    Returns string"""
    return "hello" + name
Run Code Online (Sandbox Code Playgroud)

使用鸭子类型来帮助您 如果您使用内置字符串格式或在调用 add 之前将传入值转换为字符串,则可以避免您引发的类型错误。例如,为了避免您看到的错误,您可以:

 def greeting(name: str) -> str:
    """Greeting to name
    :param name: str, the name to greet
    Returns string"""
    return "hello" + str(name)

def greeting(name: str) -> str:
    """Greeting to name
    :param name: str, the name to greet
    Returns string"""
    return "hello {}".format(name)
Run Code Online (Sandbox Code Playgroud)


hol*_*web 1

这里的线索就在行号中:当您尝试添加'Hello'和时,错误发生在函数内部3。解释器会检查类型注释的语法正确性,但不会执行其他操作。

有些项目mypy使用注释来进行状态类型检查和各种其他目的。