我有一个由多重继承定义的类B
。
class A:
def __init__(self, x, y):
self.x = x
self.y = y
class AMixin:
def __init__(self, *args, **kwargs):
# do stuff
super().__init__(*args, **kwargs)
class B(AMixin, A):
pass
基本上,mixin类会覆盖__init__
方法,但是从使用类B
的用户的角度来看,类B
的签名与A
相同。
由于我在mixin类中使用*args
和**kwargs
,因此B
的初始化是基于A
的构造函数(从功能上)。
但是,衬纸不知道这一点,他们会认为B
的签名是args
和kwargs
,这是无济于事的。
我认为这与他在检查inspect.signature
时让A
返回AMixin
的签名(而不是B
)时遇到的问题相同,但是现在这就是我得到的当我检查B
时:
from inspect import signature
signature(B).parameters.keys()
# odict_keys(['args', 'kwargs'])
如何使其返回['x', 'y']
?
答案 0 :(得分:0)
B类__init__
从AMixin
类继承。即使AMixin
用super()
和**args
调用**kwargs
,它的__init__
函数也可以根据需要执行任何逻辑。对于linter而言,扩展函数内部正在运行的内容是没有意义的。
答案 1 :(得分:0)
因此,经过一些研究,并在this post的帮助下,我提出了一种通过装饰class B
这样的解决方案:
from functools import wraps
def BaseSignature(f):
@wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
# Override signature
wrapper.__signature__ = signature(f.__mro__[2])
return wrapper
因此B
被定义为:
@BaseSignature
class B(AMixin, A):
pass
,现在signature(B)
给出了<Signature (x, y)>
,短绒棉绒也运转良好。
尽管它可以工作,但对我来说仍然不是理想的选择,因为我有几十个,并且不希望将相同的装饰器添加到所有这些装饰器中。