以下代码被 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
来自 int
至 Optional[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/