如何使用变量类型正确地对函数进行类型注释?
我正在尝试向文件系统相关库添加类型提示,其中许多函数采用 ofstr或bytestype的路径。我可以通过使用重载来处理我自己的函数,但我很难处理简单的操作或内部调用的标准库函数,这些函数是使用任一类型的参数调用的。这是一个简化的示例:
@overload
def join_paths(s1: str, s2: str) -> str: ...
@overload
def join_paths(s1: bytes, s2: bytes) -> bytes: ...
def join_paths(s1: Union[str, bytes],
s2: Union[str, bytes]) -> Union[str, bytes]:
return s1 + s2
如果我想从其他地方调用这个函数,重载工作正常,但我的问题在于s1 + s2语句,这会导致mypy发出警告:
example.py:74: error: Unsupported operand types for + ("str" and "bytes") [operator]
example.py:74: error: Unsupported operand types for + ("bytes" and "str") [operator]
我想表达的是,无论是两个操作数是类型str或两者的bytes类型,类似于做是为了使用重载我自己的函数。
我没有太多打字经验,所以我可能只是错过了明显的解决方案,但到目前为止我还没有找到如何调整它以避免警告。
回答
使用TypeVar:
from typing import TypeVar
T = TypeVar('T', str, bytes)
def join_paths(s1: T, s2: T) -> T:
return s1 + s2
join_paths("foo", "bar") # fine
join_paths(b"foo", b"bar") # fine
join_paths(1, 2) # error: T can't be int
join_paths("foo", b"bar") # error: T can't be object
当您无法通过 TypeVars 和泛型表达类型关系时,重载更像是最后的工具——有效地使用重载通常涉及#type: ignore松散类型实现主体中的大量运行时类型断言(或s)。