如何注释自定义类型 __iter__ 以正确指示非统一返回类型?

ABi*_*pth 6 python mypy python-typing

我有一个自定义类型,我想启用它的值解包(元组解包等)。我知道在 Python 中执行此操作的最简单方法是实现__iter__. 这在运行时效果很好,但我想提供类型注释,以便为每个项目返回正确的类型,例如:

import typing as t
from dataclasses import dataclass

@dataclass
class Foo:
    a: str
    b: bool

    def __iter__(self) -> t.Iterable[str, bool]:
        yield self.a
        yield self.b

Run Code Online (Sandbox Code Playgroud)

在运行时,这按预期工作:


string, bool = Foo("Hello", False)
Run Code Online (Sandbox Code Playgroud)

但是,string以上bool内容均报告为Any类型。是否有一种合理的方法可以在保留类型的同时提供此用例?

现实世界的类型不容易转换为 NamedTuple 等。

类似于如何注释多个返回值的类型?

STe*_*kov 3

您想要的功能非常特定于tuple内置,并且通过特殊外壳mypy和其他类型检查器支持。但是,您可以调整类型检查器,使其认为您的类实际上元组子类,因此它将在解包时得到类似的处理。

以下作品(游乐场):

import typing as t
from dataclasses import dataclass


if t.TYPE_CHECKING:
    base = tuple[str, bool]
else:
    base = object

@dataclass
class Foo(base):
    a: str
    b: bool
    
    def __iter__(self) -> t.Iterator[str | bool]:
        yield self.a
        yield self.b


p, q = Foo('a', True)
reveal_type(p)
reveal_type(q)
Run Code Online (Sandbox Code Playgroud)

typing.TYPE_CHECKING是一个特殊常量,它False在运行时(因此内部代码不会被执行),但True用于类型检查器。