【问题标题】:Do type annotations in Python enforce static type checking?Python 中的类型注释是否强制执行静态类型检查?
【发布时间】:2019-07-11 01:19:16
【问题描述】:

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

当我定义像the one from the doc这样的函数时

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

并尝试执行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

但是当我再次定义一个名为test的函数时

def test(a: int) -> None:
    print(a)

然后执行test("a"),我打印了a,没有出现任何错误。我也试过了

def test(a: str) -> None:
    print(a)

然后执行test(3),但没有引发 TypeError。

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

【问题讨论】:

  • greeting 引发的 TypeError 来自将整数添加到字符串中,而不是由于类型检查
  • 但是如果类型注释根本不强制类型检查,那么文档中的“静态类型检查器”是什么意思呢?

标签: python typechecking static-typing


【解决方案1】:

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

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

__annotations__

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

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

使用鸭式打字来帮助您 如果您在调用 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)

【讨论】:

    【解决方案2】:

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

    有像mypy 这样的项目将注释用于状态类型检查和各种其他目的。

    【讨论】:

      【解决方案3】:

      类型注释是cmets。它们不会以任何方式影响 Python 解释器的基本功能。 Python 不会检查你提供的参数是否与类型注解中指定的类型匹配!

      【讨论】:

        猜你喜欢
        • 2022-11-15
        • 2012-02-11
        • 2010-09-27
        • 2020-05-26
        • 1970-01-01
        • 1970-01-01
        • 2017-09-24
        • 2021-06-05
        • 1970-01-01
        相关资源
        最近更新 更多