У меня есть декоратор класса отсюда: Python связывает Dataclass и TypedDict (наследовать класс данных от TypedDict) который заставляет класс данных наследовать TypedDict путем внедрения TypedDict в класс данных.
from dataclasses import dataclass
from typing import TypedDict, Callable
def inject_fields(parent) -> Callable:
def doit(cls):
cls.__annotations__ = parent.__annotations__ | cls.__annotations__
return cls
return doit
# and then:
class UserDB(TypedDict):
id: int
@dataclass
@injectfields(UserDB)
class UserDC:
# "id: int" is injected from `TypedDict`
name: str
Как правильно напечатать функцию inject_fields? В данном случае type(parent) == UserDB и type(cls) == UserDC, но на них нельзя напрямую ссылаться в inject_fields, поскольку оба класса определяются после определения inject_fields.
Я пытался прочитать об объявлении декораторов здесь: https://mypy.readthedocs.io/en/stable/generics.html#declaring-decorators но самый правильный способ сделать это не очень ясен мне.






Хороший способ сделать это, если вы используете Python 3.12:
from typing import Any, Callable
def inject_fields[P: TypedDict, C: Any](parent: type[P]) -> Callable[[type[C]], type[C]]:
def doit(cls: type[C]) -> type[C]:
cls.__annotations__ = parent.__annotations__ | cls.__annotations__
return cls
return doit
По сути, он создает две переменные типа, P и C (для родительского и дочернего), где верхняя граница P — TypedDict, что означает, что он принимает только TypedDict или подклассы. type[P] используется, потому что P будет представлять объект TypedDict, и нам нужен тип (поэтому, по сути, вместо вызова: @inject_fields(UserDB()) мы можем использовать @inject_fields(UserDB))