将可选参数添加到内置类型的乘法继承子类的构造函数中?

时间:2010-09-20 04:02:23

标签: python python-3.x multiple-inheritance

我的多重继承权并不强大。我正在尝试创建一个超类,其__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__

1 个答案:

答案 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! - )