上文讲到 类 = 属性 + 方法
今天来讲一下方法里常见的一个特殊的方法: 名字叫 __init__ 的构造方法

1.特殊的方法 :__init__

该方法在我们实例化类的时候,python就自动调用了它,你根本就不用费力去调用它,然后才能用它(好自觉的人喏)
下面举个栗子:

class Myidol():
    def __init__(self):
        self.name = "Taylor Swift"
        self.action = "I do nothing at all"

idol = Myidol()  #实例化
idol.action
class Myidol():
    def __init__(self):
        self.name = "Taylor Swift"
        self.action = "I do nothing at all"

idol = Myidol()  #实例化
idol.action
'I do nothing at all'

从上面看到,我们只是实例化了Myidol这个类,然后__init__方法就被python调用了,我们啥也不用干就享受到了专属服务,__init__真棒

除了 self 参数,经常还会加入其他参数,都一排跟在 self 后面,排排坐

再来举栗子

class Myidol2():
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

idol2 = Myidol2("Taylor", "18", "Female")
print("%s is %s years old (●'◡'●) and she is a lovely %s." % (idol2.name, idol2.age, idol2.sex))
class Myidol2():
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

idol2 = Myidol2("Taylor", "18", "Female")
print("%s is %s years old (●'◡'●) and she is a lovely %s." % (idol2.name, idol2.age, idol2.sex))
Taylor is 18 years old (●'◡'●) and she is a lovely Female.

方法__init__必带一个参数self,它在所有参数里,排位永远第一(简直是老大),这也是类的方法与普通函数的一个区别。
当然,并不是必须写self,因为self并不是关键字,它只是一个代号,一个习惯用法。你可以写其他的,比如:beauty, handsomr_guy……都行哦
天马行空,随便你,写你所想即可。

那这个参数self到底是什么呢?
下面用实例看一下:

下面举栗子

class Noodles():
    def fun(self):
        print(self)
        print(self.__class__)

xx = Noodles()
xx.fun()
class Noodles():
    def fun(self):
        print(self)
        print(self.__class__)

xx = Noodles()
xx.fun()
<__main__.Noodles object at 0x000000A9298409E8>
<class '__main__.Noodles'>
class Noodles():
    def fun(casual):
        print(casual)
        print(casual.__class__)  #__class__用来获取类的类型
        
yy = Noodles()
yy.fun()
class Noodles():
    def fun(casual):
        print(casual)
        print(casual.__class__)  #__class__用来获取类的类型
        
yy = Noodles()
yy.fun()
<__main__.Noodles object at 0x000000A9298402E8>
<class '__main__.Noodles'>

从上面的结果看出,self实际是类的一个实例,它表示当前对象的地址。

而self的class则指向了一个类。

简单来说,self就像一个叫惯了的外号:“二狗子”。平时大家都叫你“二狗子”,有一天,警察叔叔来找你时,叫了你的大名:吴爱国。你的同事们一脸懵逼,说没听过,没见过。

Thus,用self即可,特别是新上手时,延续大家的习惯用法就可。其他的,等你进阶后再操作会更有感觉。

平常呢,我们会这样写

class Noodles():
    def fun(self, size, length):
        self.size = size
        self.length = length
class Noodles():
    def fun(self, size, length):
        self.size = size
        self.length = length

__init__方法内部,可以把各种属性绑定到self(self指向创建实例本身)。

当我们创建了__init__方法,在创建实例或者说实例化的时候,就不能传入空的参数,必须传入与__init__方法匹配的参数,但self不需要传参,Python解释器会自己吧实例变量传进去。

lunch = Noodles('medium',  25)
lunch.size      #'medium'
lunch.length   #25
lunch = Noodles('medium',  25)
lunch.size      #'medium'
lunch.length   #25

刚开始可能有点不能接受self这种写法,但是,慢慢习惯吧

2.类的继承

一般,我们都会用到类的继承,如果不能继承,那要类来干啥。不要了,扔了。

不不不,Python的类是可以继承的,儿子是可以继承爸爸的基因、财产的。别怕,乖

#语法
class DerivedClassName(BaseClassName1):  #派生类在外面,基类在括号里(英文翻译一下单词意思,自己get一下),也可以说儿子在外面,老爸在括号里
    <statement-1>
    .
    .
    .
    <statement-N>
#语法
class DerivedClassName(BaseClassName1):  #派生类在外面,基类在括号里(英文翻译一下单词意思,自己get一下),也可以说儿子在外面,老爸在括号里
    <statement-1>
    .
    .
    .
    <statement-N>

而继承又分为单继承和多继承。常见的是单继承,而多继承有时也会出现。多继承就好像你的长相,继承了你老爸、老妈、爷爷、奶奶、外公、外婆的长相的基因。额,长歪了也不能怪他们,对吧。
感恩的心,感谢有你~~

2.1 单继承
#先定义一个基类(爸爸)
class Makeup:
    type = ''
    degree = 0
    
    def __init__(self, type, degree):
        self.type = type
        self.degree = degree
        
    def Clean(self):
        ##普通清洁
        print("%s 的清洁完成" % self.type)
        
    def Water(self):
        ##普通版补水
        print("%s de补水完成,整体难度系数为%s。 " % (self.type, self.degree))
#先定义一个基类(爸爸)
class Makeup:
    type = ''
    degree = 0
    
    def __init__(self, type, degree):
        self.type = type
        self.degree = degree
        
    def Clean(self):
        ##普通清洁
        print("%s 的清洁完成" % self.type)
        
    def Water(self):
        ##普通版补水
        print("%s de补水完成,整体难度系数为%s。 " % (self.type, self.degree))
#下面写个派生类(儿子)
class SmokyMakeup(Makeup):
    steps = ''
    def __init__(self, type, degree, steps):
        self.type = type
        self.degree = degree
        self.steps = steps
        
    def Cream(self):
        #烟熏妆专用乳液
        print("%s 搽乳液完成,这次化妆有 %s 步。" % (self.type, self.steps))
#下面写个派生类(儿子)
class SmokyMakeup(Makeup):
    steps = ''
    def __init__(self, type, degree, steps):
        self.type = type
        self.degree = degree
        self.steps = steps
        
    def Cream(self):
        #烟熏妆专用乳液
        print("%s 搽乳液完成,这次化妆有 %s 步。" % (self.type, self.steps))
#实例化
test1 = SmokyMakeup("Smoky_1", "**星", 3)
print(test1.Clean())
print(test1.Water())
print(test1.Cream())
#实例化
test1 = SmokyMakeup("Smoky_1", "**星", 3)
print(test1.Clean())
print(test1.Water())
print(test1.Cream())
Smoky_1 的清洁完成
None
Smoky_1 de补水完成,整体难度系数为**星。 
None
Smoky_1 搽乳液完成,这次化妆有 3 步。
None

上面的Clean方法和Water方法就是继承了爸爸的传统,而乳液在爸爸类里没有定义,到了画烟熏妆的时候,于是自己写了新的方法,搽乳液。可以看出这是一种拓展。这里的派生类SmokyMakeup只继承了一个Makeup这个基类。

2.2 多继承

上面介绍了继承一个类,那下面介绍继承多个类。
一般多继承的语法如下:

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>
class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

在括号里,看到基类1,基类2,基类3(爸爸1,爸爸2,爸爸3)。假如在继承过程中,有两个基类存在相同名字的方法,而子类在使用这个方法时,并没有专门指定用哪个基类的方法,那么,Python会按从左到右的顺序,去找到该方法,并在调用时就用这个方法。

举栗子时间到:
我们知道化妆可以让我们变美。当然,一个人身体的健康,更是我们变美的关键。下面,我们定义一个类:

#定义一个新的类
class Health:
    height = ''
    weight = 0
    def __init__(self, type, height, weight):
        self.type = type
        self.height = height
        self.weight = weight
        
    def Water(self):
        ##每天八杯水
        print("每天八杯水,喝毕")
        
#定义一个新的类
class Health:
    height = ''
    weight = 0
    def __init__(self, type, height, weight):
        self.type = type
        self.height = height
        self.weight = weight
        
    def Water(self):
        ##每天八杯水
        print("每天八杯水,喝毕")
#多继承
class Beauty(Health, Makeup):
    def __init__(self, type, degree, height, weight):
        Makeup.__init__(self,type, degree)
        Health.__init__(self, type, height, weight)      
#多继承
class Beauty(Health, Makeup):
    def __init__(self, type, degree, height, weight):
        Makeup.__init__(self,type, degree)
        Health.__init__(self, type, height, weight)
test2 = Beauty("Smoky2", "*****星", 179, "140斤")
test2.Water()
test2 = Beauty("Smoky2", "*****星", 179, "140斤")
test2.Water()
每天八杯水,喝毕

可以看到,子类会优先继承左边父类的方法,优先级别:Base1 > Base2 > Base3 > …
想变美,还是身体健康重要呀(多喝水呀)。在这基础上,化妆后,才真的是大大大beauty。