如何为类包装器或类(其方法在 Python3 中的定义之外的其他地方分配)输入提示?

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

在某些情况下,需要向多个类注入相同的方法。为了避免重复代码,我可以使用类装饰器或类包装器将新属性和方法分配给特定类。 (由于包装器和装饰器的类型提示是相同的,所以我将以装饰器为例)

class Base:
    pass

# decorator
def decorator(cls: Input_Type) -> Output_Type:
    def new_method(self):
        pass
    cls.new_method = new_method
    return cls

# wrapper
def wrapper(cls: Input_Type) -> Output_Type:
    class WrappedClass(cls):
        def new_method(self):
            pass
    return WrappedClass

此外,为了方便和更好的可维护性,我想为这个装饰器/包装器添加类型提示(代码块中的

Output_Type
)。通过类型提示,IDE应该能够实现对原始类attr和新注入的attr的静态分析和提示。我应该如何做类型提示?

版本

python==3.8.10
VScode==1.91.1
# VScode Extensions
Pylance==v2024.7.1
Python-Type-Hint==v1.5.1

返回原始类型

我已经尝试过

typing.TypeVar
,喜欢

import typing as t
T = t.TypeVar("T", bound=t.Type)

def func(cls: T) -> T:
    ...

但是,这样,返回类型与输入类型完全相同,并且不会提示新分配的方法。

使用继承

我还尝试使用从

typing.Generic
继承并定义一个协议类,如

import typing as t
T = t.TypeVar("T", bound=t.Type)

class Injected(t.Generic[T]):
    def new_method(self): ...

def func(cls: T) -> Injected[T]:
    ...

但是这样,IDE 不会提示任何内容,无论是新方法还是原始方法。

我想知道是否有一种方法可以将新方法附加到类型提示中的现有类型(类)。

python python-typing python-decorators
1个回答
0
投票

您不需要装饰器来将属性分配给类,或创建包装类。完成您需要的操作的最简单方法就是在类范围内分配该方法。这具有与静态分析工具配合良好的优点。

def method_implementation(self, arg: int) -> set[int]:
    return set()

class Foo:
    method = method_implementation

class Bar:
    method = method_implementation
    def another_method(self, x:str) -> None:
        print(x)

你看,静态分析工具和 IDE 会理解它。使用 VSCode:

enter image description here

enter image description here

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