使用Mixin时返回基类的签名

时间:2019-01-03 20:38:07

标签: python python-3.x class mixins

我有一个由多重继承定义的类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的签名是argskwargs,这是无济于事的。

我认为这与他在检查inspect.signature时让A返回AMixin的签名(而不是B)时遇到的问题相同,但是现在这就是我得到的当我检查B时:

from inspect import signature
signature(B).parameters.keys()
# odict_keys(['args', 'kwargs'])

如何使其返回['x', 'y']

2 个答案:

答案 0 :(得分:0)

B类__init__AMixin类继承。即使AMixinsuper()**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)>,短绒棉绒也运转良好。

尽管它可以工作,但对我来说仍然不是理想的选择,因为我有几十个,并且不希望将相同的装饰器添加到所有这些装饰器中。