我在python中使用mypy
和typing
模块。想象一下,我有一个通用类型:
ContainerT = TypeVar('ContainerT')
class Thingy(Generic[ContainerT]):
pass
但是我想在与TypeVar相关的具体类型中找到另一种类型,如下例所示:
class SomeContainer(object):
Iterator = SomeCustomIterator
ContainerT = TypeVar('ContainerT')
class Thingy(Generic[ContainerT]):
def foo(self) -> ContainerT.Iterator:
pass
我收到错误消息,指出TypeVar
没有成员Iterator
。是否有另一种方法可以重新制定这种方法,以便将一种类型与另一种类型联系起来?
谢谢。
答案 0 :(得分:1)
也许您正在考虑这样的事情。
from __future__ import annotations
from abc import abstractmethod
from typing import Generic, TypeVar, Iterator, Protocol
_Iterator = TypeVar('_Iterator', bound=Iterator, covariant=True)
class SomeContainer:
iterator: Iterator[int]
def __init__(self, iterator: Iterator[int]):
self.iterator = iterator
def get_iterator(self) -> Iterator[int]:
return self.iterator
class SomeContainerProtocol(Protocol[_Iterator]):
@abstractmethod
def __init__(self, iterator: _Iterator):
pass
@abstractmethod
def get_iterator(self) -> _Iterator:
pass
_SomeContainer = TypeVar('_SomeContainer', bound='SomeContainerProtocol', covariant=True)
class Thingy(Generic[_SomeContainer]):
container: _SomeContainer
def __init__(self, container: _SomeContainer):
self.container = container
def foo(self: Thingy[SomeContainerProtocol[_Iterator]]) -> _Iterator:
pass
def bar(self) -> _SomeContainer:
pass
thingy = Thingy(SomeContainer(range(10).__iter__()))
reveal_type(thingy) # Revealed type is '...Thingy[...SomeContainer*]'
reveal_type(thingy.foo) # Revealed type is 'def () -> typing.Iterator[builtins.int]'
reveal_type(thingy.bar) # Revealed type is 'def () -> ...SomeContainer*'
您可以使用通用协议(从Python 3.8开始可用)注释self,以代替您的类型var,然后mypy将推断出迭代器的类型。