在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下标的推荐做法是什么?
答案 0 :(得分:1)
不能使用Union[...]
(别名或其他方式)作为通用类型,不能。您的联合 contents 也不是通用的,您无法使用dict
或set
声明dict
或set
对象可以包含的类型直接使用Set
或Dict
。
您有一个新的工会:
URLorStrSetOrDict = typing.Union[Set[StrOrUrl], Dict[StrOrUrl, Any]]
请注意,词典具有键和值,您需要同时提供这两个信息。如果将此用作API的输入,请考虑使用更通用且不可变的AbstractSet
和Mapping
类型;这清楚表明您的API仅需要读取信息。
就个人而言,我将努力重构一个代码库,该代码库对于它可以接受的对象种类感到困惑。要求API仅接受集合,并且现有代码必须通过set(dictionary)
而不是dictionary
传递,这并不是一项艰巨的要求,或者该API实际上可以与任何 iterable 一起使用StrOrUrl
。