从与TypeVar关联的具体类型中获取内部类型

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

我在python中使用mypytyping模块。想象一下我有一个通用类型:

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。有没有另一种方法可以重新设置它,以便我可以将一种类型与另一种类型关联?

谢谢。

python mypy
1个回答
0
投票

也许您正在考虑这样的事情。

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将推断出迭代器的类型。

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