使用TypeVar作为可调用

2024-05-17 11:14:42 发布

您现在位置:Python中文网/ 问答频道 /正文

至少根据mypy的说法,我在以下代码中遇到了一个问题:

from multiprocessing import Pool
from typing import Tuple, TypeVar

T = TypeVar("T", int, str)


def do_something(a: T) -> Tuple[T, bool]:
    # Something happening here...
    return a, False


if __name__ == "__main__":
    pool = Pool(processes=10)
    nums = list(range(100000, 1000000))
    for r in pool.imap_unordered(do_something, nums):
        if r[1]:
            print(f"Got {r[0]}")

当我使用mypy检查它时,我得到以下错误:

error: Argument 1 to "imap_unordered" of "Pool" has incompatible type "Callable[[T], Tuple[T, bool]]"; expected "Callable[[int], Tuple[T, bool]]"

实际类型显然应该满足预期类型。 是我做错了什么,还是mypy或multiprocessing.Pool中的一个bug

提前感谢您的评论


Tags: fromimportifmultiprocessingdosomethingintbool
1条回答
网友
1楼 · 发布于 2024-05-17 11:14:42

如Jasmijn的评论所示,下面是一个简单的示例:

from typing import TypeVar

T = TypeVar("T")

def do_something(a: T) -> T:
    return a

map(do_something, [1])

此操作失败,并出现相同的错误。我认为这是mypy的一个限制,但是我们可以通过引入一个额外的helper函数来修复它,通过它我们显式地提供类型,而不是mypy必须推断它

def new_do_something(t: Type[T]) -> Callable[[T], T]:
    return do_something

使用上述方法,这不再导致任何错误,同时仍然允许do_something为泛型:

map(new_do_something(int), [1])

对于原始示例,修改后的版本如下所示:

from multiprocessing import Pool
from typing import Tuple, TypeVar, Type, Callable

T = TypeVar("T", int, str)


def do_something(a: T) -> Tuple[T, bool]:
    # Something happening here...
    return a, False

def new_do_something(t: Type[T]) -> Callable[[T], Tuple[T, bool]]:
    return do_something

if __name__ == "__main__":
    pool = Pool(processes=10)
    nums = list(range(100000, 1000000))
    for r in pool.imap_unordered(new_do_something(int), nums):
        if r[1]:
            print(f"Got {r[0]}")

相关问题 更多 >