输入类装饰器的正确方法是什么?

问题描述 投票:0回答:1

我从这里有这个类装饰器:Python绑定Dataclass和TypedDict(从TypedDict继承Dataclass)它通过将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.x mypy type-hinting
1个回答
0
投票

如果你使用的是 python 3.12,一个很好的方法是:

from typing import Any

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)

© www.soinside.com 2019 - 2024. All rights reserved.