目录

  • 一、写在前面:本文仅为个人的理解,如有错误欢迎指正
  • 二、super().__init__()的含义
  • 三、代码实验
  • 四、理解super().__init__()
  • 五、Reference
  • 一、写在前面:本文仅为个人的理解,如有错误欢迎指正

    二、super().init()的含义

    我们都知道是在定义子类的__init__方法的时候,由于需要继承父类的属性,则我们需要使用到super(),那么有些情况super().__init__()里面不带参数,有些时候要写成super().__init__(*wargs, **kwargs)这就让人有些迷惑了,这里写出一点自己的理解。

    三、代码实验

    首先我们定义一个车辆类

    class Car(object):
        def __init__(self, owner, year, model):
            self.owner = owner
            self.year = year
            self.model = model 
    
        def get_info(self):
            """打印车辆信息"""
            print(f'The owner of the car is {self.owner}\n' \
                 f'The model of the car is {self.year}-{self.model}')
    

    查看一下这个类是否正常工作

    ferrari = Car('Jarry', '2021', 'Roma')
    ferrari.get_info()
    

    输出的结果:

    The owner of the car is Jarry
    The model of the car is 2021-Roma
    

    但这个时候我又想定义一个车类的子类,比如电动汽车类,那么我就应该继承Car类来减少代码量。但是为了使用Car类的属性和方法,我继承了Car类,那么我该如何初始化我的子类呢?

    第一种方法
    我只需要写我子类所需要的属性,然后父类需要的属性我用*wargs来表示,然后在__init__函数中,首先初始化我的子类的属性,将父类需要的属性打包成*wargs送入super()中

    class ElectricalCar(Car):
        def __init__(self, battery, *wargs):
            super().__init__(*wargs)  # 将剩下的参数打包送给super
            self.battery = battery  # 从参数列表中拿出battery初始化子类属性
        
        def get_power(self):
            """打印电池信息"""
            print(f'The battery of this car is {self.battery}')
    

    测试一下是否能正常工作,我们实例化一下这个电动汽车类

    tesla = ElectricalCar('10000kwh','Jarry', 2021, 'Model S')
    tesla.get_info()
    tesla.get_power()
    

    结果:

    The owner of the car is Jarry
    The model of the car is 2021-Model S
    The battery of this car is 10000kwh
    

    看来我们这样继承是正确的

    第二种方法:
    我们的父类Car由三个参数,我们定义了一个ElectricCar需要一个额外参数,那么总参数量一共是3+1=4个,如果我们把这四个参数都写出来,那不是也可以顺利继承父类。其实也可以这么做

    class ElectricalCar(Car):
        def __init__(self, battery, owner, year, model):
            super().__init__(owner, year, model)
            self.battery = battery
        
        def get_power(self):
            """打印电池信息"""
            print(f'The battery of this car is {self.battery}')
    

    测试一下

    tesla = ElectricalCar('10000kwh','Jarry', 2021, 'Model S')
    tesla.get_info()
    tesla.get_power()
    

    结果:

    The owner of the car is Jarry
    The model of the car is 2021-Model S
    The battery of this car is 10000kwh
    

    看来把参数全部写出来也是正确的,只不过这相对于第一种方法比较麻烦,但是这种方法可以方便我们理解super().__init__()

    四、理解super().init()

    super()是继承父类,那么super().__init__()代表不用实例化就可以调用父类的__init__()方法来对子类进行初始化,那么这就相当于我们实例化了一个对象,那当然需要给super().__init__()指定它的参数了,那么这样一来上面的两种方法就更好理解了。
    第一种方法super().__init__(*wargs)我们使用了任意数目的关键字参数符号*wrags来传入参数
    第二种方法super().__init__(owner, year, model)我们使用了有限的参数直接进行传入

    更好的方式super().__init__(*wargs, **kwargs)

    实质:
    灵活的方法是让祖先树中的每个方法协同设计以接受关键字参数和关键字参数字典,删除它需要的任何参数,并使用 **kwds 转发剩余的参数,最终将字典留空用于链中的最后一次调用。
    每个级别都会剥离它需要的关键字参数,以便最终的空字典可以发送到一个根本不需要参数的方法(例如,object.__init__需要零参数)

    五、Reference

    https://rhettinger.wordpress.com/2011/05/26/super-considered-super/

    物联沃分享整理
    物联沃-IOTWORD物联网 » 理解super().__init__()

    发表评论