У меня есть пакет Python, который определяет множество коллекций на основе ABC, предоставляемых collection.abc(Отображение, Последовательность и т.д.). Я хочу воспользоваться преимуществами типа hinting, введенными в Python 3.5, но у меня возникают сомнения относительно того, что будет лучшим способом для этого.
Давайте возьмем один из этих классов в качестве примера; до сих пор у меня было что-то похожее на это:
from collections.abc import Mapping
class MyMapping(Mapping):
...
Чтобы превратить это в общий тип, документация предлагает сделать что-то вроде этого:
from typing import TypeVar, Hashable, Mapping
K = TypeVar("K", bound=Hashable)
V = TypeVar("V")
class MyMapping(Mapping[K, V]):
...
Но это создает две проблемы:
-
Класс теряет все методы mixin из collection.abc.Mapping. Я мог бы справиться с этим, реализуя их сам, но это в первую очередь превзойдет часть использования ABC.
-
isinstance(MyMapping(), collections.abc.Mapping)
возвращает значение False. Кроме того, при попытке вызватьcollections.abc.Mapping.register(MyMapping)
для работы над этим возникает RuntimeError ( "Отказ создать цикл наследования" ).
Моя первая попытка решить эти проблемы состояла в том, чтобы вернуться к расширению коллекций .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]):
...
Но это не работает, поскольку collection.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]):
...
Но это пахнет рыжим. Импорт и псевдонимы громоздки, в результате класс имеет извилистую MRO, а методы смешения, предоставляемые ABC, не будут печатать информацию...
Итак, какой предпочтительный способ объявить пользовательский общий тип на основе коллекции ABC?