我想定义包含通用值列表的新类型。例如(尽可能简化):
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
?
遗憾的是,这个问题没有任何实际的好的解决方案。
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
虽然访问元组的任何类/静态函数时,此解决方案可能会导致不良结果......