如何使用变量类型正确地对函数进行类型注释?

我正在尝试向文件系统相关库添加类型提示,其中许多函数采用 ofstrbytestype的路径。我可以通过使用重载来处理我自己的函数,但我很难处理简单的操作或内部调用的标准库函数,这些函数是使用任一类型的参数调用的。这是一个简化的示例:

@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)。


以上是如何使用变量类型正确地对函数进行类型注释?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>