[英]Returning signature of base class when using a mixin
I have a class B
defined by multiple inheritance. 我有一个由多重继承定义的
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
Basically the mixin class overrides the __init__
method, but from the point of view of users using class B
, class B
's signature is same as A
. 基本上,混合类覆盖
__init__
方法,但是从使用用户类的点B
,类B
的签名是相同A
。
Since I am using *args
and **kwargs
in the mixin class, then B
's initialization is based on A
's constructor (functionally). 因为我在mixin类中使用
*args
和**kwargs
,所以B
的初始化基于A
的构造函数(在功能上)。
However, linters won't know that and they would think that B
's signature is args
and kwargs
, which is kind of unhelpful. 然而, 短信不会知道,他们会认为
B
的签名是args
和kwargs
,这有点无益。
I think this is he same problem as letting inspect.signature
return A
's signature (instead of AMixin
) when inspecting B
, but now here is what I get when I inspect B
: 我认为这是同样的问题,因为在检查
B
时让inspect.signature
返回A
的签名(而不是AMixin
),但现在这是我检查B
时得到的:
from inspect import signature
signature(B).parameters.keys()
# odict_keys(['args', 'kwargs'])
How to make it return ['x', 'y']
instead? 如何让它返回
['x', 'y']
?
Class B __init__
is inherited from AMixin
class. B类
__init__
继承自AMixin
类。 Even though AMixin
is calling super()
with **args
and **kwargs
, its __init__
function can execute any logic as you want. 即使
AMixin
使用**args
和**kwargs
调用super()
,它的__init__
函数也可以根据需要执行任何逻辑。 It doesn't make sense for linter to expand on what's being run inside a function. 对于linter来说,扩展函数内部的内容是没有意义的。
So after some research, and with the help of this post , I came up with a solution by decorating class B
as such: 经过一些研究,并在这篇文章的帮助下,我提出了一个解决方案,通过装饰
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
So then B
is defined as: 那么
B
定义为:
@BaseSignature
class B(AMixin, A):
pass
and now signature(B)
gives <Signature (x, y)>
, and the linter is also working nicely. 现在
signature(B)
给出<Signature (x, y)>
,而且linter也很好用。
Although it works, it is still not ideal for me, because I have tens of those, and not looking forward to add the same decorator to all of them. 虽然它有效,但它仍然不适合我,因为我有数十个,并没有期待为所有这些添加相同的装饰器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.