为啥没有在 python3 中检查返回类型? [复制]

Posted

技术标签:

【中文标题】为啥没有在 python3 中检查返回类型? [复制]【英文标题】:Why return type is not checked in python3? [duplicate]为什么没有在 python3 中检查返回类型? [复制] 【发布时间】:2018-02-03 04:36:45 【问题描述】:

来自PEP 484 -- Type Hints的示例

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

用str调用函数的正确方法

>>> greeting("John")
'Hello John'

如果我用 int 调用它:

>>> greeting(2)
TypeError: must be str, not int

用列表调用

>>> greeting(["John"])
TypeError: must be str, not list

一切正常,对吧? greeting 函数始终接受 str 作为参数。

但如果我尝试测试函数返回类型,例如,使用相同的函数但将返回类型更改为 int。

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

函数返回str,但类型定义为int,不会引发异常:

>>> greeting("John")
'Hello John'

另一个例子:

def greeting(name: str) -> str:
    return len(name)

>>> greeting("John")
4

虽然 PEP 484 表示返回类型应为 str,但它实际上并不类似于上面示例中可以看到的参数类型检查。

这表明 name 参数的预期类型是 str。 以此类推,预期的返回类型是 str。

是我遗漏了什么还是没有对返回类型进行类型检查?

【问题讨论】:

可能是因为你的函数参数仍然是strgreeting(name: str) 顾名思义,类型提示就是hints。当您调用函数时,python 解释器可以完全忽略它们。使用类型提示是为了让 IDE 可以为您提供有关函数参数类型的信息,并在您调用具有错误参数类型的函数时向您发出警告。在您的示例中,引发TypeError 不是因为类型提示,而是因为如果nameint,则'Hello ' + name 不起作用。 @pschill 是的,我误解了引发 TypeError 的原因,谢谢 我复制链接到的另一个问题较新且投票数较少,但我真的认为这是对问题的更好表述。 【参考方案1】:

PEP 的abstract 声明:

虽然这些注解在运行时可以通过通常的 __annotations__ 属性,运行时不进行类型检查。相反,该提案假设存在一个单独的离线类型检查器,用户可以自愿运行其源代码。本质上,这样的类型检查器充当了一个非常强大的 linter。 (虽然个人用户当然可以在运行时使用类似的检查器来执行按合同设计或 JIT 优化,但这些工具还不够成熟。)

【讨论】:

【参考方案2】:

这个问题对于python3类型提示的新手来说可能会造成一些混淆。 python3 中没有类型检查支持。这意味着如果您在参数中传递了错误的类型,python 解释器将不会引发异常。

mypy 可用于如果您需要此功能。

在上述示例中引发TypeError 的实际原因是(+) 运算符的不安全使用。 如果您使用字符串格式更改示例中提供的函数

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

上述所有情况都可以在不引发TypeError的情况下工作,并且在运行时不会进行类型检查。

类型提示被 PyCharm、PyCharm Type Hinting 等 IDE 使用,但它只是 IDE 显示的警告,而不是 python 解释器。

【讨论】:

以上是关于为啥没有在 python3 中检查返回类型? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥Java没有检查字节的类型兼容性,因为它死于int?

打字稿。为啥功能接口中描述的“返回值”类型没有严格执行?

为啥需要布尔返回类型? [复制]

为啥没有为不同的返回类型定义方法重载?

为啥 Python 3 的 'sys.modules' 中没有导入的模块?

当一个函数无返回值时,函数的类型应定义为啥