Mar*_*ost 11 python generics type-hinting python-3.x
我有一个Python包,它基于collections.abc(Mapping,Sequence等)提供的ABC定义了各种集合.我想利用Python 3.5中引入的类型提示功能,但我怀疑最好的方法是什么.
让我们以其中一个类为例; 到现在为止,我有类似这样的东西:
from collections.abc import Mapping
class MyMapping(Mapping):
...
Run Code Online (Sandbox Code Playgroud)
要将其转换为泛型类型,文档建议执行以下操作:
from typing import TypeVar, Hashable, Mapping
K = TypeVar("K", bound=Hashable)
V = TypeVar("V")
class MyMapping(Mapping[K, V]):
...
Run Code Online (Sandbox Code Playgroud)
但这会带来两个问题:
该类丢失了collections.abc.Mapping中的所有mixin方法.我可以自己处理这个实现它们,但这首先会破坏使用ABCs的部分目的.
isinstance(MyMapping(), collections.abc.Mapping)返回False.此外,尝试调用collections.abc.Mapping.register(MyMapping)解决此问题会引发RuntimeError("拒绝创建继承循环").
我解决这些问题的第一个尝试是回到扩展collections.abc.Mapping:
from typing import TypeVar, Hashable
from collections.abc import Mapping
K = TypeVar("K", bound=Hashable)
V = TypeVar("V")
class MyMapping(Mapping[K, V]):
...
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为collections.abc.Mapping不是泛型类型,并且不支持订阅运算符.所以我尝试了这个:
from typing import TypeVar, Hashable, Mapping
from collections.abc import Mapping as MappingABC
K = TypeVar("K", bound=Hashable)
V = TypeVar("V")
class MyMapping(MappingABC, Mapping[K, V]):
...
Run Code Online (Sandbox Code Playgroud)
但这闻起来很腥.导入和别名是繁琐的,由此产生的类有一个曲折的MRO,ABC提供的混合方法将没有打字信息......
那么基于集合ABC声明自定义泛型类型的首选方法是什么?
[个人意见\xe2\x84\xa2]:我不太支持创建新typing功能。这些应该足够通用,不需要对代码进行任何修改。如果您的映射类非常复杂,无法用任何常见映射(例如dict)来代替,那么您最好只使用它自己:
def foo(bar: MyMapping) -> List:\n pass\nRun Code Online (Sandbox Code Playgroud)\n\n代替
\n\ndef foo(bar: Mapping[K, V]) -> List:\n pass\nRun Code Online (Sandbox Code Playgroud)\n\n现在,如果您希望用户能够使用“键入”检查您的类typing.Mapping,您只需要子类化collections.Mapping
class MyMapping(collections.abc.Mapping):\n ... # define required methods\n\nisinstance(MyMapping(), typing.Mapping[K, V]) # --> True\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
798 次 |
| 最近记录: |