mypy
给出如下错误:
error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
的代码:
from typing import overload, Literal
from random import randint
@overload
def func() -> dict[str, float]:
...
@overload
def func() -> Literal['']: # this is the error line
...
def func() -> dict[str, float] | Literal['']:
x = randint(1, 10) % 2
if x:
return ''
else:
return {'foo':12.34}
print(func())
我尝试切换两个@overload
defs的顺序,但这没有帮助。当试图重载int
和float
或int
和bool
时,我看到了这个错误消息,我可以理解它们的相似性,但我不理解这里的问题。我也尝试了str
而不是Literal['']
,但无济于事;返回0
或False
也有类似的问题。我使用Python 3.10.4和mypy 0.960。
我在实际代码中返回''
以表示错误。
我该如何解决这个问题?
如您在上面链接的文档中所述,@overload
@overload装饰器允许描述支持多个参数类型的不同组合的函数和方法.
用于显示函数根据其参数的类型返回不同的类型。一个经典的例子是__getitem__()
,如果将int
作为参数传递,则返回单个值,但如果将slice
作为参数传递,则返回一个列表。
在你的代码中,重载的func()
有相同的签名(例如,没有参数),所以mypy
不能告诉它应该使用哪种返回类型。如果mypy
正在分析这段代码:
x = func()
它如何知道正确的返回类型?
def func() -> dict[str, float] | Literal['']:
是充分的。根据函数内部的if
,您可以返回dict或literal。
只需删除上面的代码。如果你有不同的输入类型,并依赖于不同的输出类型,overload
将是有用的,而在这个例子中,它不依赖于输入参数。
@overload
用于接受不同类型参数的函数(而不是返回不同类型)。因为func()
不接受任何参数,所以不需要@overload
:
from typing import overload, Literal
from random import randint
def func() -> dict[str, float] | Literal['']:
x = randint(1, 10) % 2
if x:
return ''
else:
return {'foo':12.34}
print(func())