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