猫哥教你写爬虫 022--类与对象(下)

类是对象的模板

1558794535243

为了完成“西红柿炒蛋”的任务,能够制造一个“炒菜机器人”,给它下达指令。

1558794563399

机器人.作菜('西红柿炒鸡蛋')
复制代码

1558794601679

【对象】,都是指【实例对象】。咱们能够以【类】为模板,屡次复制,生成多个【实例对象】

1558794640626

从模具变成产品,也就是从【类】变成【实例对象】的过程,就叫作【实例化】

成绩单代码

class 成绩单():
 @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input('请输入学生姓名:')
        cls.语文_成绩 = int(input('请输入语文成绩:'))
        cls.数学_成绩 = int(input('请输入数学成绩:'))
 @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(cls.语文_成绩))
        print('数学成绩:'+ str(cls.数学_成绩))
成绩单.录入成绩单()
成绩单.打印成绩单()
复制代码

若是咱们须要录入多份成绩呢?

若是没有学习实例化对象以前. 咱们可能要这样写...

class 成绩单1():
 @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input('请输入学生姓名:')
        cls.语文_成绩 = int(input('请输入语文成绩:'))
        cls.数学_成绩 = int(input('请输入数学成绩:'))
    
 @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(cls.语文_成绩))
        print('数学成绩:'+ str(cls.数学_成绩))
class 成绩单2():
 @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input('请输入学生姓名:')
        cls.语文_成绩 = int(input('请输入语文成绩:'))
        cls.数学_成绩 = int(input('请输入数学成绩:'))
 @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(cls.语文_成绩))
        print('数学成绩:'+ str(cls.数学_成绩))
class 成绩单3():
 @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input('请输入学生姓名:')
        cls.语文_成绩 = int(input('请输入语文成绩:'))
        cls.数学_成绩 = int(input('请输入数学成绩:'))
 @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(cls.语文_成绩))
        print('数学成绩:'+ str(cls.数学_成绩))
成绩单1.录入成绩单()
成绩单1.打印成绩单()
成绩单2.录入成绩单()
成绩单2.打印成绩单()
成绩单3.录入成绩单()
成绩单3.打印成绩单()
复制代码

有了实例化对象...

class 成绩单():
    def 录入成绩单(self):
        self.学生姓名 = input('请输入学生姓名:')
        self.语文_成绩 = int(input('请输入语文成绩:'))
        self.数学_成绩 = int(input('请输入数学成绩:'))
    def 打印成绩单(self):
        print(self.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(self.语文_成绩))
        print('数学成绩:'+ str(self.数学_成绩))
# 成绩单()类实例化为成绩单一、成绩单二、成绩单3三个【实例对象】
成绩单1 = 成绩单() # 实例化,获得实例对象“成绩单1”
成绩单2 = 成绩单() # 实例化,获得实例对象“成绩单2”
成绩单3 = 成绩单() # 实例化,获得实例对象“成绩单3”
print('如今开始录入三份成绩单:')
成绩单1.录入成绩单()
成绩单2.录入成绩单()
成绩单3.录入成绩单()
print('如今开始打印三份成绩单:')
成绩单1.打印成绩单()
成绩单2.打印成绩单()
成绩单3.打印成绩单()
复制代码

1558794845896

如何获得【实例】,如何使用【实例】,使用【实例】和直接使用【类】有什么区别?

当类须要被实例化后再使用时,和直接使用类的格式是不一样的。

咱们以前的直接使用类的代码

1558794925218

若是是实例化后再使用...

1558795009830
`
1558795112030

完整版的对比代码...

# 直接使用类
class 成绩单():
 @classmethod
    def 录入成绩单(cls):
        cls.学生姓名 = input('请输入学生姓名:')
        cls.语文_成绩 = int(input('请输入语文成绩:'))
        cls.数学_成绩 = int(input('请输入数学成绩:'))
 @classmethod
    def 打印成绩单(cls):
        print(cls.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(cls.语文_成绩))
        print('数学成绩:'+ str(cls.数学_成绩))
成绩单.录入成绩单()
成绩单.打印成绩单()
# 实例化以后
class 成绩单():   # ①不用再写@classmethod
    def 录入成绩单(self):  # ②cls变成self
        self.学生姓名 = input('请输入学生姓名:')  # ③cls.变成self.
        self.语文_成绩 = int(input('请输入语文成绩:'))
        self.数学_成绩 = int(input('请输入数学成绩:'))
    def 打印成绩单(self):
        print(self.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(self.语文_成绩))
        print('数学成绩:'+ str(self.数学_成绩))
成绩单1 = 成绩单() # ④建立实例对象:成绩单1
成绩单1.录入成绩单() # ⑤实例化后使用
成绩单1.打印成绩单()
复制代码

如下代码是直接使用类的格式,请改为实例化后再使用的格式

class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    
 @classmethod
    def 自报三围(cls):
        print('主人,个人三围是:')
        print('胸围:' + str(cls.胸围))
        print('腰围:' + str(cls.腰围))
        print('臀围:' + str(cls.臀围))
        print('哈哈哈哈哈,下面粗上面细,我长得像个圆锥。')
智能机器人.自报三围()
复制代码

实例化后再使用的代码...

class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    
    def 自报三围(self):
        print('主人,个人三围是:')
        print('胸围:' + str(self.胸围))
        print('腰围:' + str(self.腰围))
        print('臀围:' + str(self.臀围))
        print('哈哈哈哈哈,下面粗上面细,我长得像个圆锥。')
a = 智能机器人() # 实例化“智能机器人”类获得一个名字叫作“a”的实例
a.自报三围()
复制代码

cls表明“类”的意思,self表明“实例”的意思

若是把self改为别的单词呢 ? 好比bbb ?

class 智能机器人():
    胸围 = 33
    腰围 = 44
    臀围 = 55
    
    def 自报三围(bbb):
        print('主人,个人三围是:')
        print('胸围:' + str(bbb.胸围))
        print('腰围:' + str(bbb.腰围))
        print('臀围:' + str(bbb.臀围))
        print('哈哈哈哈哈,下面粗上面细,我长得像个圆锥。')
a = 智能机器人() # 实例化“智能机器人”类获得一个名字叫作“a”的实例
a.自报三围()
复制代码

self是全部类方法位于首位、默认的特殊参数。

1558795807454

实例属性和类属性有什么区别

1558795861395

class():
    变量 = 100
实例1 = 类() # 实例化
实例2 = 类() # 实例化
print(类.变量) # 100
print(实例1.变量) # 100
print(实例2.变量) # 100
复制代码

修改类属性,会致使全部实例属性变化(由于类是模板)

1558795941390

代码为证

class():
    变量 = 100
实例1 = 类() # 实例化
实例2 = 类() # 实例化
print(实例1.变量)
print(实例2.变量)
类.变量 = 'abc'   # 修改类属性
print(实例1.变量)   # 实例属性同步变化
print(实例2.变量)   # 实例属性同步变化
复制代码

修改实例属性,不会影响到其余实例,也不会影响到类。由于每一个实例都是独立的个体

1558796018752

有代码为证

# 请直接运行并体验代码
class():
    变量 = 100
实例1 = 类() # 实例化
实例2 = 类() # 实例化
print('原先的类属性:')
print(类.变量)
print('原先的实例1属性:')
print(实例1.变量)
print('原先的实例2属性:')
print(实例2.变量)
实例1.变量 = 'abc'
print('--------修改实例1的属性后----------') 
print('如今的类属性:')
print(类.变量)
print('如今的实例1属性:')
print(实例1.变量)
print('如今的实例2属性:')
print(实例2.变量)
复制代码

新增也是同样的道理,在类中新增属性会影响到实例,但在实例中新增属性只影响这个实例本身。

类新增属性...

# 请直接运行并体验代码
class():
    变量1 = 100
实例 = 类() # 实例化
类.变量2 = 'abc' # 新增类属性
print(实例.变量1)
print(实例.变量2)
复制代码

实例新增属性...

# 请直接运行并体验代码
class():
    变量1 = 100
实例 = 类() # 实例化
实例.变量2 = 'abc' # 新增实例属性
print(类.变量2)
复制代码

1558796285578

请阅读如下代码,而后想想它的运行结果将会是什么。

class 类:
    变量 = 100 #类属性
实例1 = 类() # 实例化
实例2 = 类() # 实例化
实例1.变量 = 10
类.变量 = 1
print(实例1.变量)
print(实例2.变量)
复制代码

1558796377815

实例方法和类方法的区别...

重写类方法,这会致使全部实例方法自动被重写

1558796457821

“重写类方法”分红两个步骤:

第一个步骤是在类的外部写一个函数,

第二个步骤是把这个新函数的名字赋值给类.原始函数

1558796535066

【不要加上括号】—— 写成类.原始函数() = 新函数()是错误的。

是赋值, 不是调用...

class():
    def 原始函数(self):
        print('我是原始函数!')
def 新函数(self):
    print('我是重写后的新函数!')
a = 类()  # 实例化
a.原始函数()
# 用新函数代替原始函数,也就是【重写类方法】
类.原始函数 = 新函数
# 如今原始函数已经被替换了
a.原始函数() # 重写类方法, 会波及到实例的方法...
复制代码

补全代码, 使其符合效果...

1558797088072

class 幸运():
    def 好运翻倍(self):
        print('好的,我把它存了起来,而后翻了888倍还给你:' + str(self.幸运数*888))
……
    ……
幸运.幸运数 = int(input('你的幸运数是多少?请输入一个整数。'))
……
实例 = 幸运()  # 实例化
实例.好运翻倍()
复制代码

补全以后的代码

# 请直接运行并体验代码
class 幸运():
    def 好运翻倍(self):
        print('好的,我把它存了起来,而后翻了888倍还给你:' + str(self.幸运数*888))
def 新好运翻倍(self):
    print('我是重写后的新函数!')
    print('好的,我把它存了起来,而后翻了666倍还给你:' + str(self.幸运数*666))
幸运.幸运数 = int(input('你的幸运数是多少?请输入一个整数。'))
幸运.好运翻倍 = 新好运翻倍
实例 = 幸运()  # 实例化
实例.好运翻倍()
复制代码

咱们能够经过重写类方法,让实例方法发生变化,

但咱们不能重写实例方法,模板给的技能不是说换就能换的。

1558797369845

不信 ? 来, 作个死...

class 幸运():
    def 好运翻倍(self):
        print('好的,我把它存了起来,而后翻了888倍还给你:' + str(self.幸运数*888))
def 新好运翻倍(self):
    print('我是重写后的新函数!')
    print('好的,我把它存了起来,而后翻了666倍还给你:' + str(self.幸运数*666))
幸运.幸运数 = int(input('你的幸运数是多少?请输入一个整数。'))
实例 = 幸运()  # 实例化
实例.好运翻倍 = 新好运翻倍    # 尝试重写实例方法,将会报错
实例.好运翻倍()
复制代码

1558797543177

什么是初始化函数

先上代码

class():
    def __init__(self):
        print('实例化成功!')
实例 = 类()
复制代码

初始化函数的意思是,当你建立一个实例的时候,这个函数就会被调用

__init__()的括号中,第一个参数必定要写上self,否则会报错

1558797762839

初始化函数照样能够传递参数

以前的代码...

class 成绩单():
    def 录入成绩单(self):
        self.学生姓名 = input('请输入学生姓名:')
        self.语文_成绩 = int(input('请输入语文成绩:'))
        self.数学_成绩 = int(input('请输入数学成绩:'))
    def 打印成绩单(self):
        print(self.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(self.语文_成绩))
        print('数学成绩:'+ str(self.数学_成绩))
成绩单1 = 成绩单() # 实例化
成绩单2 = 成绩单() # 实例化
成绩单3 = 成绩单() # 实例化
成绩单1.录入成绩单()
成绩单2.录入成绩单()
成绩单3.录入成绩单()
成绩单1.打印成绩单()
成绩单2.打印成绩单()
成绩单3.打印成绩单()
复制代码

咱们能够直接把须要录入的信息做为参数传递给成绩单1成绩单2成绩单3这三个实例对象。

class 成绩单():
    def __init__(self,学生姓名,语文_成绩,数学_成绩):
        self.学生姓名 = 学生姓名
        self.语文_成绩 = 语文_成绩
        self.数学_成绩 = 数学_成绩
    def 打印成绩单(self):
        print(self.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(self.语文_成绩))
        print('数学成绩:'+ str(self.数学_成绩))
成绩单1 = 成绩单('张三',99,88)
成绩单2 = 成绩单('李四',64,73)
成绩单3 = 成绩单('王五',33,22)
成绩单1.打印成绩单()
成绩单2.打印成绩单()
成绩单3.打印成绩单()
复制代码

九九乘法表...

1558797934642

三三乘法表...

1558798025445

五五乘法表

1558798070716

补全代码后,运行效果:打印了一个三三乘法表和五五乘法表

1558798249675

class 乘法表():
    def __init__(……):
        ……
    def 打印(……):
        for i in range(……):
            for x in range(1,i+1):
                print( '%d X %d = %d' % (i ,x ,i*x) ,end = ' ' )
            print(' ')
三三乘法表 = 乘法表(3)
三三乘法表.打印()
五五乘法表 = 乘法表(5)
五五乘法表.打印()
复制代码

代码答案...

# 请直接运行和体验代码
class 乘法表():
    def __init__(self,n):
        self.n = n
    def 打印(self):
        for i in range(1,self.n + 1):
            for x in range(1,i+1):
                print( '%d X %d = %d' % (i ,x ,i*x) ,end = ' ' )
            print(' ')
三三乘法表 = 乘法表(3)
三三乘法表.打印()
五五乘法表 = 乘法表(5)
五五乘法表.打印()
复制代码

代码解析...

1558798282937

小结

1558798330895

什么是继承

偶像剧里富二代继承老爹遗产,今后甩开99%同龄人,走上人生巅峰...

“类的继承”也和这个有点相似,“子类”继承了“父类”的“财产”。

类的继承很大程度也是为了不重复性劳动。

好比说当咱们要写一个新的类,若是新的类有许多代码都和旧类相同,又有一部分不一样的时候,

就能够用“继承”的方式避免重复写代码。

class 成绩单_():
    def __init__(self,学生姓名,语文_成绩,数学_成绩):
        self.学生姓名 = 学生姓名
        self.语文_成绩 = 语文_成绩
        self.数学_成绩 = 数学_成绩
    def 打印成绩单(self):
        print(self.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(self.语文_成绩))
        print('数学成绩:'+ str(self.数学_成绩))
    def 打印平均分(self):
        平均分 = (self.语文_成绩 + self.数学_成绩)/2
        print(self.学生姓名 + '的平均分是:' + str(平均分))
class 成绩单_():
    def __init__(self,学生姓名,语文_成绩,数学_成绩):
        self.学生姓名 = 学生姓名
        self.语文_成绩 = 语文_成绩
        self.数学_成绩 = 数学_成绩
    def 打印成绩单(self):
        print(self.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(self.语文_成绩))
        print('数学成绩:'+ str(self.数学_成绩))
    def 打印平均分(self):
        平均分 = (self.语文_成绩 + self.数学_成绩)/2
        print(self.学生姓名 + '的平均分是:' + str(平均分))
    def 打印总分(self):
        总分 = self.语文_成绩 + self.数学_成绩
        print(self.学生姓名 + '的总分是:' + str(总分))
实例_旧 = 成绩单_旧('王明明',99,88)
实例_旧.打印成绩单()
实例_旧.打印平均分()
实例_新 = 成绩单_新('王明明',99,88)
实例_新.打印成绩单()
实例_新.打印平均分()
实例_新.打印总分()
复制代码

1558798496335

若是运用继承来改写代码...

class 成绩单_():
    def __init__(self,学生姓名,语文_成绩,数学_成绩):
        self.学生姓名 = 学生姓名
        self.语文_成绩 = 语文_成绩
        self.数学_成绩 = 数学_成绩
    def 打印成绩单(self):
        print(self.学生姓名 + '的成绩单以下:')
        print('语文成绩:'+ str(self.语文_成绩))
        print('数学成绩:'+ str(self.数学_成绩))
    def 打印平均分(self):
        平均分 = (self.语文_成绩 + self.数学_成绩)/2
        print(self.学生姓名 + '的平均分是:' + str(平均分))
class 成绩单_(成绩单_旧):
    def 打印总分(self):
        总分 = self.语文_成绩 + self.数学_成绩
        print(self.学生姓名 + '的总分是:' + str(总分))
实例_旧 = 成绩单_旧('王明明',99,88)
实例_旧.打印成绩单()
实例_旧.打印平均分()
实例_新 = 成绩单_新('王明明',99,88)
实例_新.打印成绩单()
实例_新.打印平均分()
实例_新.打印总分()
复制代码

class 成绩单_新(成绩单_旧)就用到了类的继承,格式是class 新类(旧类)

1558798585455

旧的类称为父类,新写的类称为子类

子类能够在父类的基础上改造类方法,因此咱们能够说子类继承了父类

class 父类():
    def __init__(self,参数):
        self.变量 = 参数
    def 打印属性(self):
        print('变量的值是:')
        print(self.变量)
class 子类(父类):
    pass  # pass语句表明“什么都不作”
子类实例 = 子类(2)
子类实例.打印属性()
复制代码

1558798702165

小练习, 补全代码...

class 基础机器人():
    def __init__(self,参数):
        self.姓名 = 参数
    def 自报姓名(self):
        print('我是' + self.姓名 + '!')     
    def 卖萌(self):
        print('主人,求抱抱!')
……
    ……
        ……
安迪 = 高级机器人('安迪')
安迪.自报姓名()
安迪.卖萌()
安迪.高级卖萌()
复制代码

用到的方法...

安迪 = 高级机器人('安迪')
安迪.自报姓名()
安迪.卖萌()
安迪.高级卖萌()
复制代码

运行效果

我是安迪!
主人,求抱抱!
主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!
复制代码

补全后的代码...

class 基础机器人():
    def __init__(self,参数):
        self.姓名 = 参数
    def 自报姓名(self):
        print('我是' + self.姓名 + '!')     
    def 卖萌(self):
        print('主人,求抱抱!')
class 高级机器人(基础机器人):
    def 高级卖萌(self):
        print('主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!')
安迪 = 高级机器人('安迪')
安迪.自报姓名()
安迪.卖萌()
安迪.高级卖萌()
复制代码

子类除了能够定制新的类方法,还能直接覆盖父类的方法,

只要使用相同的类方法名称就能作到这一点。

# 请阅读注释,而后运行代码
class 基础机器人():
    def __init__(self,参数):
        self.姓名 = 参数
    def 自报姓名(self):
        print('我是' + self.姓名 + '!')     
    def 卖萌(self):
        print('主人,求抱抱!')
class 高级机器人(基础机器人):
    def 卖萌(self):  # 这里使用了相同的类方法名称“卖萌”,这样可让子类方法覆盖父类方法
        print('主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!')
鲁宾 =  基础机器人('鲁宾')
鲁宾.自报姓名()
鲁宾.卖萌()  # 调用父类方法
安迪 = 高级机器人('安迪')
安迪.自报姓名()
安迪.卖萌()  # 父类方法被子类中的同名方法覆盖
复制代码

小练习: 补全代码, 使其符合效果

class 基础机器人():
    def __init__(self,参数):
        self.姓名 = 参数
    def 自报姓名(self):
        print('我是' + self.姓名 + '!')     
    def 卖萌(self):
        print('主人,求抱抱!')
class 高级机器人(基础机器人):
    def ……
        ……
        ……
    def 卖萌(self):
        print('主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!')
安迪 = 高级机器人('安迪')
安迪.自报姓名()
安迪.高级卖萌()
复制代码

1558799010874

补全后的代码...

class 基础机器人():
    def __init__(self,参数):
        self.姓名 = 参数
    def 自报姓名(self):
        print('我是' + self.姓名 + '!')     
    def 卖萌(self):
        print('主人,求抱抱!')
class 高级机器人(基础机器人):
    def 自报姓名(self):
        print('我是高级机器人' + self.姓名 + '!')
    def 卖萌(self):
        print('主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!')
安迪 = 高级机器人('安迪')
安迪.自报姓名()
安迪.卖萌()
复制代码

咱们能在子类中重写覆盖任意父类方法,哪怕是初始化函数__init__

小练习: 补全代码, 使其符合效果

class 基础机器人():
    def __init__(self,参数):
        self.姓名 = 参数
    def 自报姓名(self):
        print('我是' + self.姓名 + '!')     
    def 卖萌(self):
        print('主人,求抱抱!')
class 高级机器人(基础机器人):
    def __init__(……):
        ……
    
    def 自报姓名(self):
        print(……)       
    def 卖萌(self):
        print('主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!')
安迪 = 高级机器人('安迪',150)
安迪.自报姓名()
安迪.卖萌()
复制代码

1558799102665

补全后的代码...

class 基础机器人():
    def __init__(self,参数):
        self.姓名 = 参数
    def 自报姓名(self):
        print('我是' + self.姓名 + '!')     
    def 卖萌(self):
        print('主人,求抱抱!')
class 高级机器人(基础机器人):
    def __init__(self,参数,参数2):
        self.姓名 = 参数
        self.智商 = 参数2
    
    def 自报姓名(self):
        print('我是高级机器人' + self.姓名 + '!' + '智商高达' + str(self.智商) + '!' )       
    def 卖萌(self):
        print('主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!')
安迪 = 高级机器人('安迪',150)
安迪.自报姓名()
安迪.卖萌()
复制代码

1558799193212

子类从【一个父类】继承类方法,咱们叫作“单继承”。还有一种更复杂的继承状况,叫“多重继承”

1558799231472

多重继承 就是一个子类从【多个父类】中继承类方法。

格式是class 子类(父类1,父类2,……)

class 基础机器人():
    def 卖萌(self):
        print('主人,求抱抱!')
# 注:由于多重继承要求父类是平等的关系,因此这里的“高级机器人”没有继承“基础机器人”
class 高级机器人(): 
    def 高级卖萌(self): 
        print('主人,每次想到怎么欺负你的时候,就感受本身全身biubiubiu散发着智慧的光芒!')
class 超级机器人(基础机器人,高级机器人):
    def 超级卖萌(self): 
        print('pika, qiu!')
        print('''   へ     /| /\7   ∠_/ / │  / / │ Z_,< /  /`ヽ │     ヽ  /  〉 Y     ` /  / イ● 、 ●  ⊂⊃〈  / () へ    | \〈 >ー、_ ィ │// /へ  / ノ<|\\ ヽ_ノ  (_/ │// 7       |/ >―r ̄ ̄`ー―_''')
        
皮卡 = 超级机器人()
皮卡.卖萌()
皮卡.高级卖萌()
皮卡.超级卖萌()
复制代码

子类超级机器人同时继承了父类基础机器人高级机器人中的类方法

多重继承有利有弊。过分使用继承容易把事情搞复杂,就像一我的有不少爹一定会带来诸多麻烦。

课堂实操

隔壁小王请你为他编写了一个出租车计费的程序html

class 出租车():
    def 计费(self):
        千米数 = float(input('请输入行程千米数:'))
        费用 = 千米数 * 2.5
        print('费用一共是:' + str(费用) + '元')
小王的出租车 = 出租车()
小王的出租车.计费()
复制代码

程序不完美的地方在于,每千米费用2.5元是一个写死的数据,没法修改。 小王但愿你能完善一下这个代码,也就是写出一个初始化函数,让这个类能接收参数(也就是每千米计费价格)生成不一样的实例。python

这样,他就能把这个程序借个隔壁的隔壁,也就是司机小李用。浏览器

补全代码, 效果以下 cookie

1558799607006

class 出租车():
    ……
        ……
        ……
    def 计费(self):
        千米数 = float(input('请输入行程千米数:'))
        费用 = 千米数 * ……
        print('费用一共是:' + str(费用) + '元')
小王的出租车 = 出租车(2.5)
小王的出租车.计费()
小李的出租车 = 出租车(3)
小李的出租车.计费()
复制代码

补全后的代码...

# 请直接运行并体验代码
class 出租车():
    def __init__(self,参数):
        self.每千米费用 = 参数    
    def 计费(self):
        千米数 = float(input('请输入行程千米数:'))
        费用 = 千米数 * self.每千米费用
        print('费用一共是:' + str(费用) + '元')
小王的出租车 = 出租车(2.5)
小王的出租车.计费()
小李的出租车 = 出租车(3)
小李的出租车.计费()
复制代码

1558800305828

这里的计费规则不太科学。司机小王对代码提出意见 小王:“我这里都是前3千米15元,后面每千米2.5元,你帮我把代码改一下,让它按个人方式计费。” session

1558800384871

修改后的代码...

class 出租车():
    def __init__(self,参数):
        self.每千米费用 = 参数
        
    def 计费(self):
        千米数 = int(input('请输入行程千米数:'))
        if 千米数<= 3:
            费用 = 15
        else:
            费用 = 15 + (千米数-3)*self.每千米费用
        print('费用一共是:' + str(费用) + '元')
小王的出租车 = 出租车(2.5)
小王的出租车.计费()
复制代码

小王:“你的代码仍是不够方便。我有时候想改为4千米20元,有时候想改为2千米12元,你这代码不支持我传递这些参数,能不能修改一下?” 补全代码后,“出租车”类能够接受3个参数,程序的运行效果不变: app

1558800518864

修改的代码...

class 出租车():
    def __init__(self,参数1,参数2,参数3):
        self.每千米费用 = 参数1
        self.最低千米 = 参数2
        self.最低费用 = 参数3
        
    def 计费(self):
        千米数 = float(input('请输入行程千米数:'))
        if 千米数<= self.最低千米:
            费用 = self.最低费用
        else:
            费用 = self.最低费用 + (千米数 - self.最低千米)*self.每千米费用
        print('费用一共是:' + str(费用) + '元')
小王的出租车 = 出租车(2.5,3,15)
小王的出租车.计费()
复制代码

重构代码,把计费函数拆解成计费记录行程统计费用结算信息四个函数:框架

class 出租车():
    def __init__(self,参数1,参数2,参数3):
        self.每千米费用 = 参数1
        self.最低千米 = 参数2
        self.最低费用 = 参数3
    
    def 计费(self):
        self.记录行程()
        self.统计费用()
        self.结算信息()
    def 记录行程(self):
        ……
    def 统计费用(self):
        ……
    def 结算信息(self):
        ……
小王的出租车 = 出租车(2.5,3,15)
小王的出租车.计费()
复制代码

程序的运行效果和刚才如出一辙: dom

1558800666611

修改的代码...

class 出租车():
    def __init__(self,参数1,参数2,参数3):
        self.每千米费用 = 参数1
        self.最低千米 = 参数2
        self.最低费用 = 参数3
    
    def 计费(self):
        self.记录行程()
        self.统计费用()
        self.结算信息()
    def 记录行程(self):
        self.行程千米数 = float(input('请输入行程千米数:'))
    def 统计费用(self):
        if self.行程千米数<= self.最低千米:
            self.最终费用 = self.最低费用
        else:
            self.最终费用 = self.最低费用 + (self.行程千米数 - self.最低千米) * self.每千米费用
    def 结算信息(self):
        print('费用一共是:' + str(self.最终费用) + '元')
小王的出租车 = 出租车(2.5,3,15)
小王的出租车.计费()
复制代码

小王对你的代码很满意。不过,开电动车的小李又跑来找你 小李:“我是开电动车的,如今政府号召环保,对电动车也补贴,全部电动车计费按8折算,你能帮我写个程序么?”scrapy

补全代码

class 出租车():
    def __init__(self,参数1,参数2,参数3):
        self.每千米费用 = 参数1
        self.最低千米 = 参数2
        self.最低费用 = 参数3
    
    def 计费(self):
        self.记录行程()
        self.统计费用()
        self.结算信息()
    def 记录行程(self):
        self.行程千米数 = float(input('请输入行程千米数:'))
    def 统计费用(self):
        if self.行程千米数<= self.最低千米:
            self.最终费用 = self.最低费用
        else:
            self.最终费用 = self.最低费用 + (self.行程千米数 - self.最低千米) * self.每千米费用
    def 结算信息(self):
        print('费用一共是:' + str(self.最终费用) + '元')
class ……:
    def ……:
        ……
小王的出租车 = 出租车(2.5,3,15)
小王的出租车.计费() 
小李的电动车 = 电动车(2.5,3,15)
小李的电动车.计费()
复制代码

效果以下...

1558800823418

补全的代码...(推荐使用继承)

class 出租车():
    def __init__(self,参数1,参数2,参数3):
        self.每千米费用 = 参数1
        self.最低千米 = 参数2
        self.最低费用 = 参数3
    
    def 计费(self):
        self.记录行程()
        self.统计费用()
        self.结算信息()
    def 记录行程(self):
        self.行程千米数 = float(input('请输入行程千米数:'))
    def 统计费用(self):
        if self.行程千米数<= self.最低千米:
            self.最终费用 = self.最低费用
        else:
            self.最终费用 = self.最低费用 + (self.行程千米数 - self.最低千米) * self.每千米费用
    def 结算信息(self):
        print('费用一共是:' + str(self.最终费用) + '元')
class 电动车(出租车):
    def 统计费用(self):
        if self.行程千米数<= self.最低千米:
            self.最终费用 = self.最低费用
        else:
            self.最终费用 = self.最低费用 + (self.行程千米数 - self.最低千米) * self.每千米费用
        self.最终费用 = self.最终费用*0.8
小王的出租车 = 出租车(2.5,3,15)
小王的出租车.计费() 
小李的电动车 = 电动车(2.5,3,15)
小李的电动车.计费()
复制代码

总结

就像是一个模版,经过这个模版能够制造出许多个实例对象,这个制造过程,咱们称之为实例化

能够经过初始化函数__init__给类传递不一样的参数,这样的方式可让咱们获得属性不一样的实例

1558800966565

有了继承以后,咱们能够很方便的改装,获得子类

这个过程就像在改装模版,咱们既能够直接复制模版,

又能够给模版增长一些功能,亦或是替换、强化原来模板的某些功能

1558801016433

今日做业

使用面向对象的方式, 来改写代码...

import time
import random
user1 = {
    'name': '',
    'life': 0,
    'victory':0
}
user2 = {
    'name': '',
    'life': 0,
    'victory':0
}
attack_list = [
    {
        'desc':'{} 挥剑向 {} 砍去',
        'num':20
    },
    {
        'desc':'{} 准备刚正面, 对 {} 使出一记"如来神掌"',
        'num':30
    },
    {
        'desc':'{} 撸起了袖子给 {} 一顿胖揍',
        'num':25
    },
    {
        'desc':'{} 向 {} 抛了个媚眼',
        'num':10
    },
    {
        'desc':'{} 抄起冲锋枪就是一梭子, {} 走位风骚, 轻松躲过',
        'num':0
    },
    {
        'desc':'{} 出了一个大招, {} 躲闪不及, 正中要害',
        'num':40
    }
]
user1['name'] = input('请输入玩家1的昵称: ')
user2['name'] = input('请输入玩家2的昵称: ')
while True:
    user1['victory'] = 0
    user2['victory'] = 0
    for i in range(3):
        print(' \n——————如今是第 {} 局——————'.format(i+1))
        user1['life'] = random.randint(100, 150)
        user2['life'] = random.randint(100, 150)
        print(user1['name']+'\n血量:{}'.format(user1['life']))
        print('------------------------')
        print(user2['name']+'\n血量:{}'.format(user2['life']))
        print('-----------------------')
        time.sleep(4)
        first_attack = random.randint(0,1)
        users_list = []
        if first_attack:
            user1['isfirst'] = 1
            print('漂亮!!! '+user1['name']+' 得到先发优点!')
            print('')
            users_list.append(user1)
            users_list.append(user2)
        else:
            user2['isfirst'] = 1
            print('难以置信! '+user2['name']+' 得到先发优点!')
            print('')
            users_list.append(user2)
            users_list.append(user1)
        time.sleep(2)
        while user1['life'] > 0 and user2['life'] > 0:
            tmp_rand = random.randint(0,len(attack_list)-1)
            users_list[1]['life'] = users_list[1]['life'] - attack_list[tmp_rand]['num']
            print(attack_list[tmp_rand]['desc'].format(users_list[0]['name'],users_list[1]['name'])+' 形成了{}点伤害 ==> '.format(attack_list[tmp_rand]['num'])+users_list[1]['name']+' 的剩余血量:{}'.format(users_list[1]['life']))
            time.sleep(4)
            if users_list[1]['life'] <= 0:
                print('')
                print(users_list[1]['name']+' 惨败 -_-||')
                users_list[0]['victory']+=1
                break
            tmp_rand = random.randint(0,len(attack_list)-1)
            users_list[0]['life'] = users_list[0]['life'] - attack_list[tmp_rand]['num']
            print(attack_list[tmp_rand]['desc'].format(users_list[1]['name'],users_list[0]['name'])+' 形成了{}点伤害 ==> '.format(attack_list[tmp_rand]['num'])+users_list[0]['name']+' 的剩余血量:{}'.format(users_list[0]['life']))
            time.sleep(4)
            if users_list[0]['life'] <= 0:
                print('')
                print(users_list[0]['name']+' 惨败 -_-||')
                time.sleep(3)
                users_list[1]['victory']+=1
                break
            print('-----------------------')
        if user1['victory'] == 2:
            print('')
            print('三局两胜中 '+user1['name']+' 获胜!')
            break
        if user2['victory'] == 2:
            print('')
            print('三局两胜中 '+user2['name']+' 获胜!')
            break
    print('')
    res = input('要不要再来一局? (回复"是"再来一局, 其余退出...) ') 
    if res != '是':
        break
复制代码

面向对象的方式...

未完待续...
复制代码

快速跳转:

猫哥教你写爬虫 000--开篇.md
猫哥教你写爬虫 001--print()函数和变量.md
猫哥教你写爬虫 002--做业-打印皮卡丘.md
猫哥教你写爬虫 003--数据类型转换.md
猫哥教你写爬虫 004--数据类型转换-小练习.md
猫哥教你写爬虫 005--数据类型转换-小做业.md
猫哥教你写爬虫 006--条件判断和条件嵌套.md
猫哥教你写爬虫 007--条件判断和条件嵌套-小做业.md
猫哥教你写爬虫 008--input()函数.md
猫哥教你写爬虫 009--input()函数-人工智能小爱同窗.md
猫哥教你写爬虫 010--列表,字典,循环.md
猫哥教你写爬虫 011--列表,字典,循环-小做业.md
猫哥教你写爬虫 012--布尔值和四种语句.md
猫哥教你写爬虫 013--布尔值和四种语句-小做业.md
猫哥教你写爬虫 014--pk小游戏.md
猫哥教你写爬虫 015--pk小游戏(全新改版).md
猫哥教你写爬虫 016--函数.md
猫哥教你写爬虫 017--函数-小做业.md
猫哥教你写爬虫 018--debug.md
猫哥教你写爬虫 019--debug-做业.md
猫哥教你写爬虫 020--类与对象(上).md
猫哥教你写爬虫 021--类与对象(上)-做业.md
猫哥教你写爬虫 022--类与对象(下).md
猫哥教你写爬虫 023--类与对象(下)-做业.md
猫哥教你写爬虫 024--编码&&解码.md
猫哥教你写爬虫 025--编码&&解码-小做业.md
猫哥教你写爬虫 026--模块.md
猫哥教你写爬虫 027--模块介绍.md
猫哥教你写爬虫 028--模块介绍-小做业-广告牌.md
猫哥教你写爬虫 029--爬虫初探-requests.md
猫哥教你写爬虫 030--爬虫初探-requests-做业.md
猫哥教你写爬虫 031--爬虫基础-html.md
猫哥教你写爬虫 032--爬虫初体验-BeautifulSoup.md
猫哥教你写爬虫 033--爬虫初体验-BeautifulSoup-做业.md
猫哥教你写爬虫 034--爬虫-BeautifulSoup实践.md
猫哥教你写爬虫 035--爬虫-BeautifulSoup实践-做业-电影top250.md
猫哥教你写爬虫 036--爬虫-BeautifulSoup实践-做业-电影top250-做业解析.md
猫哥教你写爬虫 037--爬虫-宝宝要听歌.md
猫哥教你写爬虫 038--带参数请求.md
猫哥教你写爬虫 039--存储数据.md
猫哥教你写爬虫 040--存储数据-做业.md
猫哥教你写爬虫 041--模拟登陆-cookie.md
猫哥教你写爬虫 042--session的用法.md
猫哥教你写爬虫 043--模拟浏览器.md
猫哥教你写爬虫 044--模拟浏览器-做业.md
猫哥教你写爬虫 045--协程.md
猫哥教你写爬虫 046--协程-实践-吃什么不会胖.md
猫哥教你写爬虫 047--scrapy框架.md
猫哥教你写爬虫 048--爬虫和反爬虫.md
猫哥教你写爬虫 049--完结撒花.md函数

相关文章
相关标签/搜索