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

发布于 2025-01-13 15:46:24 字数 759 浏览 3 评论 0原文

我有一个自定义类型,我想启用它的值解包(元组解包等)。我知道在 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 和 <上面的 code>bool 被报告为 Any 类型。是否有一种合理的方法可以在保留类型的同时提供此用例?

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

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

I have a custom type, for which I'd like to enable unpacking its values (a la tuple unpacking, etc.). The simplest way I know to do this in Python is to implement __iter__. This works great at runtime but I'd like however to provide type annotations so that the correct types are returned for each item, for example:

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

At runtime, this works as-expected:


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

However, string and bool above are reported as Any types. Is there a reasonable way to provide this use-case whilst preserving types?

The real-world type is not easily translate-able to a NamedTuple etc.

Similar-ish to How to annotate types of multiple return values?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你丑哭了我 2025-01-20 15:46:24

您想要的功能非常特定于 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
    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 对于类型检查器。

The feature you want is very specific to tuple builtin, and is supported via special-casing in mypy and other type checkers. However, you can tweak the type checker to make it think that your class is actually a tuple subclass, so it will get similar treatment on unpacking.

The following works (playground):

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 is a special constant which is False at runtime (so the code inside is not executed), but True for type checkers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文