如何从类装饰器访问 TypeVariable 的实例

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

我正在创建一个类装饰器,但在正确输入时遇到了一些问题。下面是一个最小的可重现示例,它运行(没有运行时错误)但让 pylance(使用静态类型检查器 pyright)抱怨。

我的问题是,包装函数中的

cls
Type[T@wrapper]
(在这个例子中实现了
Type[Base]
,而不是
Base
)。这会导致
cls.__init__ = init
引发 pyright 错误
cannot be assigned to member "__init__" of class "type"
.

我试图避免在整个 Decorator 定义中使用 T 而不是 Type[T],这会导致以下 pyright 错误:

Argument of type "Type[Base]" cannot be assigned to parameter of type "T@Decorator"
  Type "Type[Base]" cannot be assigned to type "Base"
    "Type[type]" is incompatible with "Type[Base]"

所以看起来 Decorator 期望的是 Type 而不是 Type-instance。如果这是正确的,那么问题是:如何从类装饰器访问 TypeVariable 的实例?

from typing import Any, Callable, TypeVar, Optional, Dict, Union, Generic, Type

class Base:
    def __init__(self, config: str):
        self.config = config    

T = TypeVar('T', bound=Base)

def Decorator(arg: str) -> Callable[[Type[T]], Type[T]]:

    def wrapper(cls: Type[T]) -> Type[T]:

        # remember original initializer
        _init = cls.__init__

        # updated initializer
        def init(self: T, config: str, *args, **kwargs):
            _init(self, config, *args, **kwargs)  
            setattr(self, arg, config)

        # set updated initializer
        cls.__init__ = init # <-------- type missmatch
    
        # return class with updated initializer and 
        return cls

    return wrapper


@Decorator('test')
class Test(Base):
    test: str

    def task(self):
        print("test module dummy task: ", self.test)

虽然代码按预期工作,但所描述的问题让我思考我是否在这里采取了正确的方法。

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