python - 默认参数是否会覆盖 mypy 的类型提示?

标签 python nonetype mypy python-typing default-parameters

以下代码被 mypy 拒绝正如预期的那样:

def foo(value: int) -> None:
    print(value, type(value))
foo(None)

输出:

error: Argument 1 to "foo" has incompatible type "None"; expected "int"

但是在引入一个默认参数None之后,没有错误了:

def foo(value: int=None) -> None:
    print(value, type(value))
foo(None)

我希望 mypy只允许 None (作为参数和默认值)如果我们改变 value来自 intOptional[int] ,但似乎不需要这样做。为什么?

最佳答案

当您让关键字参数接受 None 时,mypy 会隐式地使该参数成为 Optional[Blah] 类型(如果它还没有)。您可以通过将 reveal_type(...) 函数添加到您的代码并运行 mypy 来查看:

def foo(value: int = None) -> None:
    print(value, type(value))

reveal_type(foo)
foo(None)

输出将是:

test.py:4: error: Revealed type is 'def (value: Union[builtins.int, None] =)'

(请务必在实际运行代码之前删除 reveal_type,因为该函数在运行时实际上并不存在——它只是由 mypy 特制以帮助调试。)

这种行为的存在主要是因为它有助于减少函数签名的噪音。毕竟,如果 value 在某些时候允许为 None,显然它必须同时接受 int 和 None。在那种情况下,为什么不直接将类型推断为 Optional[int](相当于 Union[int, None],顺便说一句),这样用户就不会需要重复相同的信息两次?

当然,并不是每个人都喜欢这种行为:有些人更喜欢直截了当。在这种情况下,使用 --no-implicit-optional 标志运行 mypy。这将产生以下输出:

test.py:1: error: Incompatible default for argument "value" (default has type "None", argument has type "int")
test.py:4: error: Revealed type is 'def (value: builtins.int =)'
test.py:5: error: Argument 1 to "foo" has incompatible type "None"; expected "int"

当然,您需要更改函数签名。

如果您想以各种其他方式提高 mypy 的严格性,请尝试传递 --strict 标志。这将自动启用 --no-implicit-optional 和其他几个严格标志。有关详细信息,请运行 mypy --help

关于python - 默认参数是否会覆盖 mypy 的类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51055952/

相关文章:

python - 在字符串列表中将 None 更改为 Float (Python)

python - 为什么 mypy 看不到来自 typeshed 的类型?

python - Mypy 不支持的类型 Type[typeVarAlias]

python - 如何确定 python 中任何生成器的产量/发送/返回值

python - 如何找到扭曲服务器内存使用量增加的根源?

python - 如何将用户定义的函数应用于每个 numpy 数组元素

python - NoneType-Python 中的 Yield 错误

go - python“不退还”等价物

python - 在 plotly dash 中,如何将本地镜像文件提供给 dash.html.Img?

Python Mechanize 表单例份验证错误