python - 绕过“typing.Union 不是泛型类”
问题描述
在 Python 的typing
模块中,似乎任何不是泛型类型的东西都不支持下标:
>>> 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
定义的情况。(至少在 Python 3.7 中。)typing.Union
typing.TypeVar
看起来有一种方法可以进行子类化Generic
,大概像:
class SetOrDict(typing.Generic[StrOrURL]):
# ...
但这会立即引起TypeError: Parameters to Generic[...] must all be type variables
。
有没有办法适应上述情况?即,下标用户定义(非通用)类型定义的推荐做法是什么?
解决方案
您不能使用Union[...]
、 别名或其他方式作为泛型类型,不。您的联合内容也不是通用的,您无法直接使用or来说明一个dict
或set
对象可以包含哪些类型,您将使用or 。dict
set
Set
Dict
你有一个新的工会:
URLorStrSetOrDict = typing.Union[Set[StrOrUrl], Dict[StrOrUrl, Any]]
请注意,字典有键和值,您需要提供两者的信息。如果这用作 API 的输入,则考虑使用更通用和不可变AbstractSet
的Mapping
类型;这清楚地表明您的 API 只需要读取信息。
就个人而言,我会努力重构一个代码库,该代码库对于它可以接受哪些类型的对象如此混乱。要求 API 只接受集合并且必须传入现有代码set(dictionary)
而dictionary
不是一个艰巨的要求,或者该 API 可能真的可以与任何可迭代的StrOrUrl
.
推荐阅读
- python - 正则表达式匹配子字符串中的字符并排除尾随字符
- python - 在文件夹中的多个文件上运行 Python 脚本
- javascript - 纪元时间到底是什么时候?在 PHP 中转换客户端时区的纪元?
- react-native - 如何使用原生模块创建 react-native android 模块?
- excel - Excel SUMIFS 检查列是否包含文本
- c# - C#如何通过Linq查询为每个数据行在现有数据表中添加一列?
- database - 每日交付系统的数据库模式?
- javascript - 在函数中渲染 JSX 元素
- sql - 如何替换 SQL 更新查询中的分隔列值?
- java - Fortify 认为强类型对象上存在日志伪造,除非我手动调用 .toString()