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

问题描述 投票:0回答:1

我有一个自定义类型,我想启用它的值解包(元组解包等)。我知道在 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

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


string, bool = Foo("Hello", False)

但是,上面的

string
bool
被报告为
Any
类型。有没有一种合理的方法来提供这个用例,同时保留类型?

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

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

python mypy python-typing
1个回答
5
投票

您想要的功能非常特定于

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

以下作品(游乐场):

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
    if not t.TYPE_CHECKING:
        def __iter__(self) -> t.Iterable[str | bool]:
            yield self.a
            yield self.b


p, q = Foo('a', True)
reveal_type(p)
reveal_type(q)

typing.TYPE_CHECKING
是一个特殊的常量,在运行时是
False
(所以里面的代码不会被执行),但是对于类型检查器来说是
True

© www.soinside.com 2019 - 2024. All rights reserved.