python3.4中NamedTuple中的通用列表

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

我想定义包含通用值列表的新类型。例如(尽可能简化):

from typing import NamedTuple, TypeVar, List
T = TypeVar('T')
MyType = NamedTuple('MyType', [('values', List[T])])

但这不起作用,并且

mypy
报告以下错误:

a.py:4: error: Type variable "a.T" is unbound
a.py:4: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
a.py:4: note: (Hint: Use "T" in function signature to bind "T" inside a function)
Found 1 error in 1 file (checked 1 source file)

不幸的是,我需要python3.4兼容性(请不要问为什么),所以我不能使用“dataclass”版本。

我试图通过将

#type: ignore
添加到
MyType
定义来忽略它,但随后
mypy
即使在这样的结构中也想添加类型:

def do_stuff(x: MyType) -> None:
    for v in x.values:
        pass

说:

error: Need type annotation for 'v'

有什么方法可以让这个在python3.4下工作还是我必须继续添加

# type: ignore

python generics mypy python-3.4 python-typing
1个回答
1
投票

遗憾的是,这个问题没有任何实际的好的解决方案。

NamedTuple
Generic
真的很不喜欢彼此……

最好/唯一的解决方案是区分类型检查和运行时 - 但你仍然需要破解启用通用参数......

from typing import NamedTuple, TypeVar, List, Generic, TYPE_CHECKING
T = TypeVar('T')

if TYPE_CHECKING:
    class MyType(Generic[T]):
        values: List[T]

        def __init__(values: List[T]):
            pass
else:
    # enabling MyType[int] needs some bad hacking though...
    _MyType = NamedTuple('MyType', [('values', list)])
    class _Helper:
        def __call__(self, *args, **kwargs) -> _MyType:
            return _MyType(*args, **kwargs)

        def __getitem__(self, _type: type) -> Type[_MyType]:
            return _MyType

     MyType = _Helper()


def foo(arg: MyType[int]): # works now
    for v in arg:
       ...

instance = MyType([1,2,3]) # works as well

虽然访问元组的任何类/静态函数时,此解决方案可能会导致不良结果......

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