You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Python多继承的所有父类接收相同的kwargs参数?

实现多继承下所有父类获取同一组关键字参数

问题原因

你示例中的Second拿到空kwargs,是因为First的__init__调用super时没有传递*args和**kwargs。即使修正这个问题,默认情况下如果某个父类从kwargs中弹出键,后续父类也会丢失该键。要让所有父类都能获取完整的原始kwargs(除非显式弹出),可以用以下几种方案:


方案一:手动调用每个父类的__init__

绕过super链,直接在子类中调用每个父类的初始化方法,传递完整参数。这种方法简单直接,适合父类之间无依赖的场景。

class First(object):
    def __init__(self, *args, **kwargs):
        print('First', kwargs)

class Second(object):
    def __init__(self, *args, **kwargs):
        print('Second', kwargs)

class Third(First, Second):
    def __init__(self, *args, **kwargs):
        # 手动调用所有父类的初始化方法,传递完整参数
        First.__init__(self, *args, **kwargs)
        Second.__init__(self, *args, **kwargs)
        print('Third', kwargs)

测试输出:

In [1]: tc = Third(key='value', someother='nothing')
First {'key': 'value', 'someother': 'nothing'}
Second {'key': 'value', 'someother': 'nothing'}
Third {'key': 'value', 'someother': 'nothing'}

注意:该方法会跳过Python的MRO机制,如果父类依赖super链的后续初始化逻辑,可能引发问题。


方案二:预存原始kwargs到实例属性

在子类中先把完整的kwargs保存到实例,父类优先从实例获取原始参数,同时保留super链的兼容性。

class First(object):
    def __init__(self, *args, **kwargs):
        # 优先使用实例预存的原始kwargs,无则用传入的参数
        current_kwargs = getattr(self, '_original_kwargs', kwargs)
        print('First', current_kwargs)
        # 若需要弹出键,操作副本避免影响其他父类
        # local_kwargs = current_kwargs.copy()
        # target_key = local_kwargs.pop('key', None)
        super().__init__(*args, **kwargs)

class Second(object):
    def __init__(self, *args, **kwargs):
        current_kwargs = getattr(self, '_original_kwargs', kwargs)
        print('Second', current_kwargs)
        super().__init__(*args, **kwargs)

class Third(First, Second):
    def __init__(self, *args, **kwargs):
        # 预存原始kwargs到实例
        self._original_kwargs = kwargs.copy()
        super().__init__(*args, **kwargs)
        print('Third', kwargs)

测试输出:

In [2]: tc = Third(key='value', someother='nothing')
Second {'key': 'value', 'someother': 'nothing'}
First {'key': 'value', 'someother': 'nothing'}
Third {'key': 'value', 'someother': 'nothing'}

方案三:在super链中传递kwargs副本

每个父类调用super时传递kwargs的副本,确保后续父类拿到的是完整参数,不受当前父类的修改影响。

class First(object):
    def __init__(self, *args, **kwargs):
        print('First', kwargs)
        # 传递kwargs副本给下一个父类
        super().__init__(*args, kwargs.copy())

class Second(object):
    def __init__(self, *args, **kwargs):
        print('Second', kwargs)
        super().__init__(*args, kwargs.copy())

class Third(First, Second):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, kwargs.copy())
        print('Third', kwargs)

测试输出:

In [3]: tc = Third(key='value', someother='nothing')
Second {'key': 'value', 'someother': 'nothing'}
First {'key': 'value', 'someother': 'nothing'}
Third {'key': 'value', 'someother': 'nothing'}

如果需要在父类中弹出特定键,操作副本即可:

class First(object):
    def __init__(self, *args, **kwargs):
        local_kwargs = kwargs.copy()
        key = local_kwargs.pop('key', None)
        print('First 获取到key:', key, '剩余参数:', local_kwargs)
        # 仍传递原始副本给后续父类
        super().__init__(*args, kwargs.copy())

内容的提问来源于stack exchange,提问作者TM5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:53:07