类是对象的模板

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

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

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

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

成绩单代码

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

如果我们需要录入多份成绩呢?

如果没有学习实例化对象之前. 我们可能要这样写...

class 成绩单1():
    @classmethoddef 录入成绩单(cls):cls.学生姓名 = input('请输入学生姓名:')cls.语文_成绩 = int(input('请输入语文成绩:'))cls.数学_成绩 = int(input('请输入数学成绩:'))    @classmethoddef 打印成绩单(cls):print(cls.学生姓名 + '的成绩单如下:')print('语文成绩:'+ str(cls.语文_成绩))print('数学成绩:'+ str(cls.数学_成绩))
class 成绩单2():
    @classmethoddef 录入成绩单(cls):cls.学生姓名 = input('请输入学生姓名:')cls.语文_成绩 = int(input('请输入语文成绩:'))cls.数学_成绩 = int(input('请输入数学成绩:'))
    @classmethoddef 打印成绩单(cls):print(cls.学生姓名 + '的成绩单如下:')print('语文成绩:'+ str(cls.语文_成绩))print('数学成绩:'+ str(cls.数学_成绩))
class 成绩单3():
    @classmethoddef 录入成绩单(cls):cls.学生姓名 = input('请输入学生姓名:')cls.语文_成绩 = int(input('请输入语文成绩:'))cls.数学_成绩 = int(input('请输入数学成绩:'))
    @classmethoddef 打印成绩单(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.数学_成绩))
# 成绩单()类实例化为成绩单1、成绩单2、成绩单3三个【实例对象】
成绩单1 = 成绩单() # 实例化,得到实例对象“成绩单1”
成绩单2 = 成绩单() # 实例化,得到实例对象“成绩单2”
成绩单3 = 成绩单() # 实例化,得到实例对象“成绩单3”
print('现在开始录入三份成绩单:')
成绩单1.录入成绩单()
成绩单2.录入成绩单()
成绩单3.录入成绩单()
print('现在开始打印三份成绩单:')
成绩单1.打印成绩单()
成绩单2.打印成绩单()
成绩单3.打印成绩单()
复制代码

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

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

我们之前的直接使用类的代码

如果是实例化后再使用...

`

完整版的对比代码...

# 直接使用类
class 成绩单():
    @classmethoddef 录入成绩单(cls):cls.学生姓名 = input('请输入学生姓名:')cls.语文_成绩 = int(input('请输入语文成绩:'))cls.数学_成绩 = int(input('请输入数学成绩:'))
    @classmethoddef 打印成绩单(cls):print(cls.学生姓名 + '的成绩单如下:')print('语文成绩:'+ str(cls.语文_成绩))print('数学成绩:'+ str(cls.数学_成绩))
成绩单.录入成绩单()
成绩单.打印成绩单()
# 实例化之后
class 成绩单():   # ①不用再写@classmethoddef 录入成绩单(self):  # ②cls变成selfself.学生姓名 = 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    @classmethoddef 自报三围(cls):print('主人,我的三围是:')print('胸围:' + str(cls.胸围))print('腰围:' + str(cls.腰围))print('臀围:' + str(cls.臀围))print('哈哈哈哈哈,下面粗上面细,我长得像个圆锥。')
智能机器人.自报三围()
复制代码

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

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

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

如果把self改成别的单词呢 ? 比如bbb ?

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

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

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

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

修改类属性,会导致所有实例属性变化(因为类是模板)

代码为证

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

修改实例属性,不会影响到其他实例,也不会影响到类。因为每个实例都是独立的个体

有代码为证

# 请直接运行并体验代码
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)
复制代码

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

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

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

重写类方法,这会导致所有实例方法自动被重写

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

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

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

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

是赋值, 不是调用...

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

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

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('你的幸运数是多少?请输入一个整数。'))
幸运.好运翻倍 = 新好运翻倍
实例 = 幸运()  # 实例化
实例.好运翻倍()
复制代码

我们可以通过重写类方法,让实例方法发生变化,

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

不信 ? 来, 做个死...

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

什么是初始化函数

先上代码

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

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

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

初始化函数照样可以传递参数

之前的代码...

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.打印成绩单()
复制代码

九九乘法表...

三三乘法表...

五五乘法表

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

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 = ndef 打印(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)
五五乘法表.打印()
复制代码

代码解析...

小结

什么是继承

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

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

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

比如说当我们要写一个新的类,如果新的类有许多代码都和旧类相同,又有一部分不同的时候,

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

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

如果运用继承来改写代码...

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

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

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

子类可以在父类的基础上改造类方法,所以我们可以说子类继承了父类

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

小练习, 补全代码...

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散发着智慧的光芒!')
安迪 = 高级机器人('安迪')
安迪.自报姓名()
安迪.高级卖萌()
复制代码

补全后的代码...

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)
安迪.自报姓名()
安迪.卖萌()
复制代码

补全后的代码...

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

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

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

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

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

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

多重继承有利有弊。过度使用继承容易把事情搞复杂,就像一个人有很多爹必定会带来诸多麻烦。

课堂实操

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

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

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

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

补全代码, 效果如下

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)
小李的出租车.计费()
复制代码

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

修改后的代码...

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

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

修改的代码...

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

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

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

程序的运行效果和刚才一模一样:

修改的代码...

class 出租车():def __init__(self,参数1,参数2,参数3):self.每公里费用 = 参数1self.最低公里 = 参数2self.最低费用 = 参数3def 计费(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折算,你能帮我写个程序么?”

补全代码

class 出租车():def __init__(self,参数1,参数2,参数3):self.每公里费用 = 参数1self.最低公里 = 参数2self.最低费用 = 参数3def 计费(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)
小李的电动车.计费()
复制代码

效果如下...

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

class 出租车():def __init__(self,参数1,参数2,参数3):self.每公里费用 = 参数1self.最低公里 = 参数2self.最低费用 = 参数3def 计费(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__给类传递不同的参数,这样的方式可以让我们得到属性不同的实例

有了继承之后,我们可以很方便的改装,得到子类

这个过程就像在改装模版,我们既可以直接复制模版,

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

今日作业

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

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'] = 0user2['victory'] = 0for 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'] = 1print('漂亮!!! '+user1['name']+' 获得先发优势!')print('')users_list.append(user1)users_list.append(user2)else:user2['isfirst'] = 1print('难以置信! '+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']+=1breaktmp_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']+=1breakprint('-----------------------')if user1['victory'] == 2:print('')print('三局两胜中 '+user1['name']+' 获胜!')breakif user2['victory'] == 2:print('')print('三局两胜中 '+user2['name']+' 获胜!')breakprint('')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

转载于:https://juejin.im/post/5cfc4ad86fb9a07eb15d4896

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

  1. 猫哥教你写爬虫 046--协程-实践-吃什么不会胖

    吃什么不会胖? 低热量食物 食物的数量有千千万,如果我们要爬取食物热量的话,这个数据量必然很大. 使用多协程来爬取大量的数据是非常合理且明智的选择 如果我们要爬取的话,那就得选定一个有存储食物热量信息 ...

  2. 猫哥教你写爬虫 006--条件判断和条件嵌套

    流程控制 复仇者联盟3-无限战争(搜集宝石) python里面, 不需要使用;来结尾, 因为python是使用换行来结束一行代码的 if判断, 没有{}, python使用缩进来表示层级关系 if.. ...

  3. 猫哥教你写爬虫 002--作业-打印皮卡丘

    作业 请你使用print()函数将下面的皮卡丘打印出来, 使用三种方式 へ /|/\7 ∠_// │ / /│ Z _,< / /`ヽ│ ヽ / 〉Y ` / /イ● 、 ● ⊂⊃〈 /() へ ...

  4. 猫哥教你写爬虫 005--数据类型转换-小作业

    小作业 程序员的一人饮酒醉 请运用所给变量,使用**str()**函数打印两句话. 第一句话:1人我编程累, 碎掉的节操满地堆 第二句话:2眼是bug相随, 我只求今日能早归 number1 = 1 ...

  5. 猫哥教你写爬虫 004--数据类型转换-小练习

    小练习, 改一下代码 word = '3.8' number = 1 sentence = '人工智障说:3.8+1等于' print(sentence+str(int(float(word)+num ...

  6. 猫哥教你写爬虫 037--爬虫-宝宝要听歌

    戴上耳机, 这个世界与我无关... 让我们用音乐洗涤心灵吧... 我们从哪个网站爬取资源呢? 专治各种不服... 打开酷狗官网, 可以看到搜索框,我们要爬取的数据就是搜索歌曲后, 酷狗后台返回的歌曲列 ...

  7. 猫哥教你写爬虫 027--模块介绍

    time模块 import time # 时间对象转美式时间字符串 print(time.asctime()) # Wed May 29 09:25:07 2019 print(time.asctim ...

  8. 猫哥教你写爬虫 000--开篇

    写在前面 快速跳转: 猫哥教你写爬虫 000--开篇.md 猫哥教你写爬虫 001--print()函数和变量.md 猫哥教你写爬虫 002--作业-打印皮卡丘.md 猫哥教你写爬虫 003--数据类 ...

  9. OpenGL.Shader:志哥教你写一个滤镜直播客户端(5)视觉滤镜:对比度、曝光、马赛克

    OpenGL.Shader:志哥教你写一个滤镜直播客户端(5) 上一章介绍了如何在渲染nv21流的时候进行滤镜的无缝切换,这章内容紧接上一章,介绍三种滤镜特效:对比度.曝光.马赛克,并介绍如何动态调节 ...

  10. OpenGL.Shader:志哥教你写一个滤镜直播客户端:仿3个抖音滤镜效果(4镜像/电击/灵魂出窍)

    OpenGL.Shader:志哥教你写一个滤镜直播客户端(可能是结束篇) OpenGL.Shader基本的图像处理知识已经学习的7788了,所以这篇应该是滤镜直播客户端的最后一篇了,之后会出基于FFm ...

最新文章

  1. 物联网通信协议全解析
  2. IDEA实现到JSTL
  3. Interview:算法岗位面试—10.11下午—上海某公司算法岗位(偏机器学习,互联网数字行业)技术面试考点之XGBoost的特点、python的可变不可变的数据类型、赋值浅拷贝深拷贝区别
  4. 应用系统瓶颈排查和分析的思考-Arthas 实战
  5. Hyperledger Fabric 1.0 实例简析 第一课 network_setup.sh分析
  6. 字节流复制文本文件【应用】
  7. MapReduce Job本地提交过程源码跟踪及分析
  8. 实体类blob类型_Mysql的数据类型和JPA的实体类
  9. ssms只有空白解决方案_SSMS中的解决方案和项目概述
  10. 服务器传文件的工具,向服务器传文件的工具
  11. binlog2sql快速闪回
  12. 迈普路由器访问控制列表配置命令_迈普路由器配置手册
  13. hook IE 总结
  14. android控件覆盖方法
  15. 邹恒甫:谈点2002年后海鬼/龟和特聘教授的工资待遇和福利
  16. python签到脚本_基于Python实现签到脚本过程解析
  17. 独立服务器和vps的区别
  18. 华硕 内存条 不同步_千元级的RGB台式内存条——让你的主机流光溢彩
  19. 解决WIN10下应用商店不能用,闪退的情况
  20. (附源码)SSM校园一卡通管理系统JAVA计算机毕业设计项目

热门文章

  1. 【DZX修改】根据性别不同显示不同的默认头像
  2. vue mand-mobile ui加class不起作用的问题 css权重问题
  3. 移动端框架之mand-mobile
  4. SAP中 关于BAPI_MATERIAL_SAVEDATA创建物料报错:字段MARA-MEINS/BAPI_MARA-BASE_UOM(_ISO)被定义为必需的字段; 它不包含条目
  5. 中南大学计算机学院复试2021,34所自划线院校2021考研复试分数线-2021中南大学考研分数线已公布...
  6. Nothing Phone 1智能手机;索尼X系列三款便携式蓝牙音箱;三星第二代SmartSSD计算存储驱动器 | 科技新品...
  7. win10msmpeng占内存_win10内存占用率太高怎么办
  8. TPA4411RTJR 无电容立体声耳机驱动器 封装:QFN20
  9. OpenGL编程(四)改变窗口大小时保持图形的原形
  10. jcp jsr_Oracle提交了第三次JCP改革JSR,以提高透明度