python - 向内置类型的多重继承子类的构造函数添加可选参数?

标签 python python-3.x multiple-inheritance

我的多重继承能力不强。我正在尝试创建一个父类(super class),其 __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__ 的签名),但只要父类(super class)出现在子类的 MRO 中并定义内置类型之前,它就可以工作__new__ 这种方式让我可以创建使用不同内置类型的子类,而无需为每个类型添加单独的 __new__

>>> class Super(object):
    name = None
    def __new__(cls, *args, name=None, **kwargs):
        inner = super().__new__(cls, *args, **kwargs)
        inner.name = name
        return inner

>>> class Sub(Super, int):
    pass

>>> Sub(5)
5

>>> Sub(5, name="Foo")
5

>>> _.name
'Foo'

最佳答案

你不能将任意参数(无论是位置参数还是命名参数)传递给同样任意的父类(super class)(即“无论当前叶类型是什么,mro 中的前一个类型”)——大多数类型和类只是不接受任意参数,这也是出于极好的原因——引用自 Zen of Python 的中间部分,

Errors should never pass silently.
Unless explicitly silenced.

在大多数情况下,调用(例如)int(name='booga')当然会出错。

如果你想让你的名字怪异的 class Super 能够“传递”任意参数,你还必须确保所有用作基础的类都可以处理 - 所以,例如,int 可以用一个参数(或恰好两个:一个字符串和一个基数)调用,因此,如果 class Sub 对您来说绝对重要可以从推卸责任的 Super int 中乘以继承,你必须填写它,例如:

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 本身,它有一个无情的 __new__!-)

关于python - 向内置类型的多重继承子类的构造函数添加可选参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3748635/

相关文章:

python - 获取具有整数或 bool 索引的 numpy 数组 View

python - 属性错误 : module 'sklearn.mixture' has no attribute 'GMM'

python - 无法在 python 中导入/安装任何库

python:基类中的多重继承和__add__()

C++接口(interface)多重继承,方法相同

python - 如何使用 python 和来自 html 标签值下的 html 标签的漂亮汤解析 html 文件?

python字符串到函数: globals() vs sys.模块与字典

inheritance - 多重继承什么时候派上用场?

python - Pandas :使用分组数据创建滞后列

python - 从字典列表理解中返回 True 或 False