在学习 Python 3.10 新特性时,其中有个类型别名(TypeAlias), 所举的例子是
StrCache = 'Cache[str]' # a type alias
LOG_PREFIX = 'LOG[DEBUG]' # a module constant
可写成
StrCache: TypeAlias = 'Cache[str]' # a type alias
LOG_PREFIX = 'LOG[DEBUG]' # a module constant
这让 StrCache 更像是一个类型别名,而不是一个看起来明显就是 Cache[str]
的字符串变量(实际上它确实是)。
本文不在 TypeAlias 本身,而是从 Cache[str]
能看出 Python 似乎也能支持像 Java 那样的泛型, 就像 Python 内置支持的 List[str] 或 list[str] 那样。
那么来看 Python 怎么去实现一个只能放入字符串的 Cache[str]
Cache, 而不能放入别的类型。
我们依然用到的是 Python 的 typing 模块,所以上面代码仍然是属于类 type hints 的范畴,对 Python 解释器不构成约束,只会影响到 mypy 这样的检查工具
使用上面的类
使用 python test.py
命令执行一切正常,输出为
abc
123
但在 IntelliJ IDEA 中,上面高亮的第五行 cache.put('b', 123)
行上会提示
Expected type 'str' (matched generic type 'T'), got 'int' instead
如果用 mypy
来检测
$ mypy tt.py
tt.py:13: error: Incompatible return value type (got "Optional[T]", expected "T")
tt.py:21: error: Argument 2 to "put" of "Cache" has incompatible type "int"; expected "str"
Found 2 errors in 1 file (checked 1 source file)
typing 模块中除了上面用到的 Generic, TypeVar 外,还有更多的类型约束,像 Mapping, Iterator, Sequence。还有更多的类似于 Java 的泛型功能
泛型子类型
泛型函数
更多用法,在此不一一列出。写自己的实现代码使用泛型的需要其实并不大,除非做第三方的通用库会用到泛型写法,这让别人用起来更清晰。
更多功能请参考 https://mypy.readthedocs.io/en/stable/generics.html
链接:
本文链接 https://yanbin.blog/python-generic-implementation/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。