使用 mixin 时返回 base class 的签名
Returning signature of base class when using a mixin
我有一个 class 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 class 覆盖了 __init__
方法,但是从使用 class B
, class [=13] 的用户的角度来看=]的签名与A
相同。
由于我在 mixin class 中使用 *args
和 **kwargs
,因此 B
的初始化是基于 A
的构造函数(功能上)。
然而,linters 不会知道这一点,他们会认为 B
的签名是 args
和 kwargs
,这有点没用。
我认为这与检查 B
时让 inspect.signature
return A
的签名(而不是 AMixin
)的问题相同,但是现在这是我检查 B
时得到的结果:
from inspect import signature
signature(B).parameters.keys()
# odict_keys(['args', 'kwargs'])
如何做到 return ['x', 'y']
?
ClassB__init__
继承自AMixin
class。尽管 AMixin
使用 **args
和 **kwargs
调用 super()
,但它的 __init__
函数可以执行您想要的任何逻辑。 linter 扩展函数内部的内容 运行 没有意义。
所以经过一些研究,在 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)>
,而且 linter 也运行良好。
虽然它有效,但对我来说仍然不理想,因为我有几十个,并且不希望为所有这些添加相同的装饰器。
我有一个 class 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 class 覆盖了 __init__
方法,但是从使用 class B
, class [=13] 的用户的角度来看=]的签名与A
相同。
由于我在 mixin class 中使用 *args
和 **kwargs
,因此 B
的初始化是基于 A
的构造函数(功能上)。
然而,linters 不会知道这一点,他们会认为 B
的签名是 args
和 kwargs
,这有点没用。
我认为这与检查 B
时让 inspect.signature
return A
的签名(而不是 AMixin
)的问题相同,但是现在这是我检查 B
时得到的结果:
from inspect import signature
signature(B).parameters.keys()
# odict_keys(['args', 'kwargs'])
如何做到 return ['x', 'y']
?
ClassB__init__
继承自AMixin
class。尽管 AMixin
使用 **args
和 **kwargs
调用 super()
,但它的 __init__
函数可以执行您想要的任何逻辑。 linter 扩展函数内部的内容 运行 没有意义。
所以经过一些研究,在 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)>
,而且 linter 也运行良好。
虽然它有效,但对我来说仍然不理想,因为我有几十个,并且不希望为所有这些添加相同的装饰器。