避开“打字。工会不是通用类”

时间:2019-01-08 14:39:18

标签: python python-3.x type-hinting

在Python的typing模块中,似乎所有非generic类型的内容都不支持下标:

>>> import typing
>>> from yarl import URL

>>> StrOrURL = typing.Union[URL, str]
>>> typing.List[StrOrURL]                # OK; List is generic
typing.List[typing.Union[yarl.URL, str]]

>>> SetOrDict = typing.Union[set, dict]
>>> SetOrDict[StrOrURL]                  # Raises
TypeError: typing.Union[set, dict] is not a generic class

无论SetOrDict是用typing.Union还是typing.TypeVar定义的,都是这种情况。 (至少在Python 3.7中)。

似乎有一种子类Generic的子类,大概是这样的:

class SetOrDict(typing.Generic[StrOrURL]):
    # ...

但这会立即引发TypeError: Parameters to Generic[...] must all be type variables

有没有办法容纳以上情况?即,为用户定义的(非通用)typedef下标的推荐做法是什么?

1 个答案:

答案 0 :(得分:1)

不能使用Union[...](别名或其他方式)作为通用类型,不能。您的联合 contents 也不是通用的,您无法使用dictset声明dictset对象可以包含的类型直接使用SetDict

您有一个新的工会:

URLorStrSetOrDict = typing.Union[Set[StrOrUrl], Dict[StrOrUrl, Any]]

请注意,词典具有键和值,您需要同时提供这两个信息。如果将此用作API的输入,请考虑使用更通用且不可变的AbstractSetMapping类型;这清楚表明您的API仅需要读取信息。

就个人而言,我将努力重构一个代码库,该代码库对于它可以接受的对象种类感到困惑。要求API仅接受集合,并且现有代码必须通过set(dictionary)而不是dictionary传递,这并不是一项艰巨的要求,或者该API实际上可以与任何 iterable 一起使用StrOrUrl