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

Python中super().__init__(**kwargs)及多重继承使用问题求助

Python中super()用法问题解答

咱们逐个拆解你遇到的两个问题,同时也会聊聊super()结合**kwargs的正确姿势,以及多重继承里super()的使用要点。

问题1:输出中额外出现None的原因

先看你的代码里的get_rate方法:

def get_rate(self):
    print('The hourly rate of {} is {} '.format(self.firstname, self.rate))

这个方法内部用print输出内容,但它没有返回值——Python中,没有return语句的函数默认会返回None。当你执行print(hourlystaff1.get_rate())时,其实是两步操作:

  1. 调用get_rate(),它自己会打印出The hourly rate of Bob is $15
  2. 打印这个方法的返回值,也就是None

所以最终输出会多出一个None。

修正方案(二选一):

  • 方案1:让get_rate返回字符串,外部再打印:
    def get_rate(self):
        return 'The hourly rate of {} is {} '.format(self.firstname, self.rate)
    # 调用时
    print(hourlystaff1.get_rate())
    
  • 方案2:直接调用get_rate,不用print包裹:
    def get_rate(self):
        print('The hourly rate of {} is {} '.format(self.firstname, self.rate))
    # 调用时
    hourlystaff1.get_rate()
    

另外补充:你的Employee类里all_staff列表没有初始化,记得加上all_staff = []类属性,否则会报错。

问题2:TypeError的原因与修正

你这段代码的错误点有好几个,咱们逐个说:

  1. 参数定义不匹配:Hourly的__init__只定义了self和rate两个参数,但你实例化时传了5个位置参数('Bob', 'Bar', '23', '12/1/2019'),超出了方法的参数接收范围,直接触发TypeError。
  2. 未定义kwargs参数却使用:Hourly的__init__里写了super().__init__(**kwargs),但kwargs根本没在方法的参数列表里声明,会导致NameError(如果前面的TypeError没触发的话)。
  3. 父类参数未传递:你想给Employee传递的firstname、lastname等参数,没有在Hourly的__init__里处理,也没传给父类。
  4. __str__方法格式字符串参数不匹配:你的__str__里写了6个占位符,但只传了5个参数,会触发IndexError。

正确结合super()与**kwargs的写法

核心思路是:每个子类只处理自己专属的参数,把剩下的参数通过**kwargs传递给父类,让父类去处理它关心的参数,这样在继承链(尤其是多重继承)中参数传递会更灵活。

修正后的代码:

class Employee:
    def __init__(self, firstname='', lastname='', age='', dob='', **kwargs):
        # 先处理当前类的参数,再把剩余kwargs传给父类(这里父类是object,空kwargs不会报错)
        super().__init__(**kwargs)
        self.firstname = firstname
        self.lastname = lastname
        self.age = age
        self.dob = dob

class Hourly(Employee):
    # 接收自己专属的rate参数,用**kwargs接收父类需要的所有其他参数
    def __init__(self, rate='', **kwargs):
        self.rate = rate
        # 把kwargs传给父类,父类会处理firstname、lastname等参数
        super().__init__(**kwargs)

    def __str__(self):
        # 修正占位符和参数的匹配问题
        return "{} {}\nAge: {}\nDOB: {}\nHourly Rate: {}".format(
            self.firstname, self.lastname, self.age, self.dob, self.rate
        )

    def get_rate(self):
        print('The hourly rate of {} is {} '.format(self.firstname, self.rate))

# 用关键字参数传递,清晰不易错
bob = Hourly(firstname='Bob', lastname='Bar', age='23', dob='12/1/2019', rate='$12')
bob.get_rate()

super()与**kwargs结合的要点及多重继承注意事项

结合**kwargs的核心优势

它能让你在继承链中避免重复定义父类的参数,每个类只关注自己的专属参数,剩下的交给上层父类处理,极大提升代码的可维护性,尤其是在多重继承场景下。

多重继承中super()的关键要点

  1. 遵循方法解析顺序(MRO):super()不是直接调用父类方法,而是按照Python的MRO顺序调用继承链中的下一个类的方法。你可以通过ClassName.__mro__查看某个类的MRO顺序,比如print(Hourly.__mro__)。
  2. 所有类的__init__都要调用super():确保继承链上的每个类都能完成初始化逻辑,并且要把未处理的**kwargs传递下去,直到继承链的末端(通常是object类,它的__init__不接受额外参数,所以最后要确保没有多余的kwargs)。
  3. 优先使用关键字参数:位置参数在多重继承中很容易导致参数匹配混乱,用关键字参数传递能明确每个参数的归属,避免错误。
  4. 不要忽略super()的参数:在某些复杂的多重继承场景下,可能需要显式指定super()的类和实例参数(比如super(ChildClass, self).__init__(**kwargs)),不过Python3中默认的无参super()已经能处理大部分场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:32