如何正确键入 hint a class 装饰器?
How to properly type hint a class decorator?
假设我们有一些函数 func
将 class A
的实例映射到 class B
的实例,即它具有签名 Callable[[A], B]
.
我想为 A
的子 class 编写一个 class 装饰器 autofunc
,它会在创建实例时自动将 func
应用于实例。例如,考虑基于全局环境变量的自动 jit 编译。这可以通过
完成
from functools import wraps
def autofunc(basecls):
@wraps(basecls, updated=())
class WrappedClass(basecls):
def __new__(cls, *args, **kwargs):
instance = basecls(*args, **kwargs)
return func(instance)
return WrappedClass
那么下面两个大致等价:
<b>class</b> C(A):
...
instance = func(C())
@autofunc
<b>class</b> C(A):
...
instance = C()
出于天真,我试过了
def autofunc(basecls: type[A]) -> type[B]:
@wraps(basecls, updated=())
class WrappedClass(basecls):
def __new__(cls, *args, **kwargs):
instance = basecls(*args, **kwargs)
return func(instance)
return WrappedClass
mypy
非常不喜欢,引发错误:
error: Variable "basecls" is not valid as a type [valid-type]
error: Invalid base class "basecls" [misc]
- 还有一个问题是
WrapperClass.__new__
returns 是 B
而不是 WrapperClass
的实例。
目前有没有什么方法可以正确输入这样的提示 class 装饰器,或者 mypy
还不能用这个吗?
示例代码:
from functools import wraps
class A:
pass
class B:
pass
def func(cl: A) -> B:
print(f"Replacing {cl=}")
return B()
def autofunc(basecls: type[A]) -> type[B]:
@wraps(basecls, updated=())
class WrappedClass(basecls):
def __new__(cls, *args, **kwargs):
instance = basecls()
return func(instance)
return WrappedClass
这只是 mypy
中的一个错误:https://github.com/python/mypy/issues/5865
假设我们有一些函数 func
将 class A
的实例映射到 class B
的实例,即它具有签名 Callable[[A], B]
.
我想为 A
的子 class 编写一个 class 装饰器 autofunc
,它会在创建实例时自动将 func
应用于实例。例如,考虑基于全局环境变量的自动 jit 编译。这可以通过
from functools import wraps
def autofunc(basecls):
@wraps(basecls, updated=())
class WrappedClass(basecls):
def __new__(cls, *args, **kwargs):
instance = basecls(*args, **kwargs)
return func(instance)
return WrappedClass
那么下面两个大致等价:
<b>class</b> C(A): ... instance = func(C()) |
@autofunc <b>class</b> C(A): ... instance = C() |
---|
出于天真,我试过了
def autofunc(basecls: type[A]) -> type[B]:
@wraps(basecls, updated=())
class WrappedClass(basecls):
def __new__(cls, *args, **kwargs):
instance = basecls(*args, **kwargs)
return func(instance)
return WrappedClass
mypy
非常不喜欢,引发错误:
error: Variable "basecls" is not valid as a type [valid-type]
error: Invalid base class "basecls" [misc]
- 还有一个问题是
WrapperClass.__new__
returns 是B
而不是WrapperClass
的实例。
目前有没有什么方法可以正确输入这样的提示 class 装饰器,或者 mypy
还不能用这个吗?
示例代码:
from functools import wraps
class A:
pass
class B:
pass
def func(cl: A) -> B:
print(f"Replacing {cl=}")
return B()
def autofunc(basecls: type[A]) -> type[B]:
@wraps(basecls, updated=())
class WrappedClass(basecls):
def __new__(cls, *args, **kwargs):
instance = basecls()
return func(instance)
return WrappedClass
这只是 mypy
中的一个错误:https://github.com/python/mypy/issues/5865