如何解决如何注释带有默认值的 AnyStr 的函数?
我希望对采用 AnyStr
参数的函数进行类型注释,该参数默认为 str
并返回相同类型的 AnyStr
。但是,如果我这样写:
from typing import AnyStr
def func(s: AnyStr = ".") -> AnyStr:
return s
然后 mypy 失败并显示“Incompatible default for argument "s" (default has type "str",argument has type "bytes")
”。
我还尝试将代码拆分为 .py
和 .pyi
文件,如下所示:
.py
文件:
def func(s = "."):
return s
.pyi
文件:
from typing import AnyStr
def func(s: AnyStr = ...) -> AnyStr:
...
...但我一定是错误地调用了 mypy,因为它无法对 func
的调用进行类型检查;例如,如果我将 func(42)
添加到 .py
文件中,mypy 不会抱怨。
注释我的函数并使代码完全经过类型检查的正确方法是什么?
解决方法
使用 None
作为默认值,然后在函数内部使用两种强制转换:一种将 None
替换为“。”转换为 Optional[AnyStr]
,并将返回值转换为 AnyStr
。
def func(s : AnyStr = None) -> AnyStr:
if s is None:
s = cast(Optional[AnyStr],".")
return cast(AnyStr,s)
编辑:我原来的答案失败了,因为类型检查忽略了具体的实现:
一种可能性是使用 overload
来枚举 AnyStr
所涵盖的两种情况:
from typing import overload
@overload
def func(s: str = ".") -> str:
pass
@overload
def func(s: bytes) -> bytes:
pass
def func(s):
return s
,
此案例已讨论 here。 Guido 特别是回答:
我认为这里的问题是一般来说,例如如果还有其他参数也在其类型中使用 _T
,则默认值将不起作用。由于这是唯一的参数,您可以说这是过度限制,如果没有参数,则返回类型应仅由该默认值确定(在您的简化示例中,您希望它返回 {{1 }})。但我并不那么热衷于这样做,因为一旦使用另一个泛型参数它就会中断。
基于该线程,您可以使用以下解决方法:
int
,
也许这就是你想要的:
@overload
def func(s: str=...) -> str: ...
@overload
def func(s: bytes) -> bytes: ...
@overload
def func(s: None) -> str: ...
def func(s="."):
return s
r1 = func()
reveal_type(r1)
r2 = func("1")
reveal_type(r2)
r3 = func(b"1")
reveal_type(r3)
Mypy: The stdout of the command line is:
note: Revealed type is 'builtins.str'
note: Revealed type is 'builtins.str'
note: Revealed type is 'builtins.bytes'
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。