高级泛型类型注释

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

我有一个包装类(<init>>是我正在努力解决的部分):

T = TypeVar('T')

class Wrapper(Generic[T]):
    def __init__(**kwargs: <<T.__init__>>):
        self.kwargs = kwargs
        ...

    def __call__() -> T:
        return self.__orig_class__.__args__[-1](**self.kwargs)

我是这样使用的:

wrapped_class = Wrapper[SomeClass](**SomeClass_arguments)

SomeClass_arguments 是 SomeClass 传递给其 init 方法的参数

我想对 SomeClass_arguments 进行静态类型检查和提示。 我能够使用检查模块动态检查它们。但我更喜欢静态解决方案。我并不总是可以控制 SomeClass,因为它可以是我的类,也可以是某些第三方类。

我无法讨论这个设计的真正意图。但我需要包装(添加一些级别的功能)一个对象,同时分离对象定义

wrapped_class = Wrapper[SomeClass](**SomeClass_arguments)
和初始化wrapped_class()。

python generics annotations wrapper type-variables
1个回答
0
投票

你可以试试这个:

from typing import Callable, Generic, ParamSpec, TypeVar

T = TypeVar('T')
P = ParamSpec('P')

class Wrapper(Generic[T]):
    def __init__(self, cls: Callable[P, T], *args: P.args, **kwargs: P.kwargs):
        self._cls = cls
        self.args = args
        self.kwargs = kwargs

    def __call__(self) -> T:
        return self._cls(*self.args, **self.kwargs)

wrap = Wrapper(int, '123')  # OK
wrap = Wrapper(int, [])  # gives error: list not compatible with arguments of int

它使用

Callable[P, T]
(其中 P 是
ParamSpec
)来指定类型。
P
是从第一个参数和传递的参数推断出来的。

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