Предположим, библиотека Python определяет интерфейс, предназначенный для реализации сторонним кодом. Как эта библиотека может предоставить фабричную функцию, которая создает экземпляры этих реализаций с надлежащей статической безопасностью типов?
Пример
Рассмотрим библиотеку, которая определяет протокол для фигур и предоставляет фабричную функцию, которая создает экземпляры (встроенные или сторонние) на основе строкового ключа и пересылает аргументы конструктора.
Реализации могут иметь разные конструкторы параметры.
Код: Выделить всё
# core.py
from typing import Protocol, Any
class Shape(Protocol):
def area(self) -> float: ...
def perimeter(self) -> float: ...
SHAPE_REGISTRY: dict[str, type[Shape]] = {}
def register_shape(name: str, cls: type[Shape]) -> None:
SHAPE_REGISTRY[name] = cls
def create_shape(kind: str, **kwargs: Any) -> Shape:
cls = SHAPE_REGISTRY[kind]
return cls(**kwargs)
Код: Выделить всё
# shapes.py
from core import Shape, register_shape
class Circle:
def __init__(self, radius: float):
self.radius = radius
def area(self) -> float: return 3.14 * self.radius ** 2
def perimeter(self) -> float: return 2 * 3.14 * self.radius
class Square:
def __init__(self, side: float):
self.side = side
def area(self) -> float: return self.side ** 2
def perimeter(self) -> float: return 4 * self.side
register_shape("circle", Circle)
register_shape("square", Square)
Код: Выделить всё
shape1 = create_shape("circle", radius=1)
shape2 = create_shape("square", side=2)
Однако я хотел бы предоставить подсказки статического типа, чтобы:
- Тип возвращаемого значения create_shape("circle", radius=1) выводился как Circle
- Аргументы ключевых слов radius и Side проверялись средством проверки типов
/> - Сторонние пакеты могут регистрировать новые фигуры (например, Rectangle, Triangle) без изменения базовой библиотеки
Вопрос:
Есть ли способ сделать динамически расширяемую фабричную функцию, подобную этой, типобезопасной, чтобы средства проверки статических типов (такие как mypy илиpyright) могли по-прежнему выводить правильные параметры конструктора и возвращаемые типы, в том числе для классов, зарегистрированных сторонними организациями?
Нужно ли мне:
- Перепроектировать реестр или фабрику шаблон?
- Использовать систему параметров на основе TypedDict?
- Или это возможно только с помощью специального плагина mypy?
Подробнее здесь: https://stackoverflow.com/questions/798 ... classes-in
Мобильная версия