Мой вопрос: правильно ли мое использование AnyType
(как я определил его ниже)? Цель состоит в том, чтобы AnyType
мог принять любой объект класса, но экземпляры объектов класса, или типов функций, или других вещей, не относящихся к типу type
, должны быть отклонены.
подробности:
У меня есть класс, который выглядит примерно так:
MixinSubclsType = Type["ChildRegistryMixin"]
AnyType = Type[type] # <- is this correct?
class ChildRegistryMixin:
"""Mixin class that creates classes which track subclasses.
Each new child class will track its own children."""
_subclasses: Dict[Any, MixinSubclsType] = dict()
_make_reg_key: Callable[[AnyType], Any]] = lambda subcls: getattr(subcls, "__name__")
def __init_subclass__(subcls,
make_reg_key: Optional[Callable[[AnyType], Any]]] = None,
**kwargs) -> None:
# implementation here
Является ли Type[type]
правильным способом сказать контролеру типов, что lambda
должен принимать только объекты класса?
Поскольку больше информации иногда лучше, чем меньше, ниже приведена вся реализация.
class ChildRegistryMixin:
"""Mixin class that creates classes which track subclasses.
Each new child class will track its own children.
Usage example 1:
class RegisteredByName(ChildRegistryMixin): ...
assert ChildRegistryMixin._subclasses["RegisteredByName"] is RegisteredByName
Usage example 2:
valid_lookup = dict(ClassName="othername")
class RegisteredByPop(ChildRegistryMixin,
make_reg_key=lambda subcls:
valid_lookup.pop(subcls.__name__)):
pass
class ClassName(RegisteredByPop): ...
assert RegisteredByPop._subclasses["othername"] is ClassName
class InvalidName(RegisteredByPop): ... # <-- ERROR!
"""
_subclasses: Dict[Any, MixinSubclsType] = dict()
_make_reg_key: Callable([AnyType], Any) = lambda subcls: getattr(subcls, "__name__")
def __init_subclass__(subcls,
make_reg_key: Optional[Callable([AnyType], Any)] = None,
**kwargs) -> None:
super().__init_subclass__(**kwargs)
# for later child classes of the new class
subcls._subclasses = dict()
# child added to the reg of closest parent that is a subclass of CRB
for parent_cls in subcls.mro()[1:]:
if issubclass(parent_cls, ChildRegistryMixin):
break
else:
parent_cls = ChildRegistryMixin
# make the key
key = parent_cls._make_reg_key(subcls)
# can't have multiple child classes with same key
if key not in parent_cls._subclasses:
parent_cls._subclasses[key] = subcls
else:
raise ChildRegistryError(f"Attempted to overwrite the "
f"child class key {key!r} in the "
f"{parent_cls.__name__} registry")
# inherit the subclass' key maker from parent if one was not provided
subcls._make_reg_key = parent_cls._make_reg_key if make_reg_key is None\
else make_reg_key