我的多重继承权并不强大。我正在尝试创建一个超类,其__init__
采用可选的命名参数及其子类,它也从内置类型继承。可悲的是,我似乎不知道如何做这项工作:
>>> class Super(object):
name = None
def __init__(self, *args, name=None, **kwargs):
self.name = name
super().__init__(self, *args, **kwargs)
>>> class Sub(Super, int):
pass
>>> Sub(5)
5
>>> Sub(5, name="Foo")
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
Sub(5, name="Foo")
TypeError: 'name' is an invalid keyword argument for this function
(我也在没有super()
调用的情况下尝试过,但结果是一样的。)
也许对多重继承有更好了解的人可以指出我正确的方向?
更新
以下是我最终提出的解决方案,基于Alex's answer。
它仍然有点hacky(通过构建中途__new__
的签名),但只要超类出现在内置类型之前的子类'MRO中并定义{{1这种方式允许我创建使用不同内置类型的子类,而不为每个类型添加单独的__new__
。
__new__
答案 0 :(得分:3)
你不能将任意参数(无论是位置的还是命名的)传递给一个同样任意的超类(即“当前叶子类型的mro
中的前一个类型”) - 大多数类型和类只是不接受任意参数,原因也很好 - 引自Zen of Python
,
Errors should never pass silently.
Unless explicitly silenced.
在大多数情况下,调用(例如)int(name='booga')
当然会出错。
如果您希望奇怪命名的class Super
能够“传递”任意参数,您还必须确保所有类在它可以处理之后作为基础使用 - 例如,{可以使用一个参数(或者恰好两个:字符串和基数)调用{1}},因此,如果int
可以多次继承,则对您来说绝对至关重要通过class Sub
和 int,你必须填写,例如:
Super
请注意,您必须覆盖class Int(int):
def __new__(cls, *a, **k):
return int.__new__(Int, a[0] if a else 0)
,不 __new__
(如果您也覆盖后者,则无益,但无论如何都无关紧要):__init__
是不可变的,因此值必须设置为int
时间。
现在,比如
__new__
的工作。但请注意,>>> class X(Super, Int): pass
...
>>> X(23, za='zo')
23
>>>
必须来自X
(我们的Int
- 消毒版__new__
),不来自int
本身,这是非常恰当的int
! - )