前言
前文传送门:
Python面向对象编程从零开始(2)—— 与对象相互了解:Python面向对象编程从零开始(2)-- 与对象相互了解
Python面向对象编程从零开始(3)—— 小姐姐请客上篇:Python面向对象编程从零开始(3)-- 小姐姐请客上篇
分割线---------------------------------------------------------------------------------------------------------------------------
又到了新的一周,继续连载啊,哈哈
上次故事说到小姐姐请我吃大(pao)餐(mian),在煮泡面的过程中出了点问题,就是,不管煮多久泡面还是生的。
于是,意识到是代码写的有问题,我们开始修改代码。
class Cook_instant_noodles:
def __init__(self):
self.cookedState = '生的'
self.cookedLevel = 0
def __str__(self):
return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
def cook(self,cooked_time):
if cooked_time >= 0 and cooked_time < 3:
self.cookedState = '还没熟'
elif cooked_time >= 3 and cooked_time < 5:
self.cookedState = '半生不熟'
elif cooked_time >= 5 and cooked_time < 8:
self.cookedState = '煮熟了'
elif cooked_time >= 8:
self.cookedState = '煮糊了'
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()
print(instant_noodles)
#开始煮泡面
instant_noodles.cook(20)
之前发现煮了20分钟,还是生的
泡面煮不熟的原因竟然是
原因在于:
程序执行的流程可以理解为这样:
1.创建了一个对象
2.初始化
3.打印状态
4.打印信息调用(这时候输出的是初始化的信息,所以显示生的)
5.对象调用cook方法,煮20分钟
6.改变属性(cookedState)(这时候属性被改变为 煮糊了)
初步解决问题--更新输出信息
所以,问题出在,我们改变了属性,却没有把改变后的属性显示出来。
所以在最后加上一句即可:
print(instant_noodles)
完整代码:
class Cook_instant_noodles:
def __init__(self):
self.cookedState = '生的'
self.cookedLevel = 0
def __str__(self):
return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
def cook(self,cooked_time):
if cooked_time >= 0 and cooked_time < 3:
self.cookedState = '还没熟'
elif cooked_time >= 3 and cooked_time < 5:
self.cookedState = '半生不熟'
elif cooked_time >= 5 and cooked_time < 8:
self.cookedState = '煮熟了'
elif cooked_time >= 8:
self.cookedState = '煮糊了'
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()
print(instant_noodles)
#开始煮泡面
instant_noodles.cook(20)
print(instant_noodles)
面临新问题,接受挑战!
观察结果,虽然第二次煮了20分钟煮糊了,状态得到改变了,但是,时间却还是显示0分钟,这是为什么呢?
我们回看代码:
我们在cook方法中,通过传参改变的只有cookedState,却没改变cookedLevel的值,所以cookedLevel一直保持初始值为0
再次解决问题--属性大展风采
为了解决这个问题,我们要找个变量,就像累加器一样,每次调用cook方法,我就加上相应的值
那么,在类中,变量其实可以认为用属性替代
我们将cookedLevel这一属性作为累加器
self.cookedLevel += cooked_time
self.cookedLevel += cooked_time 可以理解为 self.cookedLevel = self.cookedLevel + cooked_time
但两者并不是完全相同,以后可能会讲到
这样,每次煮的时间就能累加存储进去了
注意:对象多次调用某个方法,则要想用到上次的结果则要找到当前对象的一个属性,让属性值变化,因为属性值在对象结束时才消失(即理解为关掉程序则消失)
class Cook_instant_noodles:
def __init__(self):
self.cookedState = '生的'
self.cookedLevel = 0
def __str__(self):
return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
def cook(self,cooked_time):
self.cookedLevel += cooked_time
if cooked_time >= 0 and cooked_time < 3:
self.cookedState = '还没熟'
elif cooked_time >= 3 and cooked_time < 5:
self.cookedState = '半生不熟'
elif cooked_time >= 5 and cooked_time < 8:
self.cookedState = '煮熟了'
elif cooked_time >= 8:
self.cookedState = '煮糊了'
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()
print(instant_noodles)
#开始煮泡面
instant_noodles.cook(20)
print(instant_noodles)
这下,问题总算是解决了
小姐姐的新困扰--宝宝没煮过面啊
虽然煮面功能完成了,但是小姐姐提出了新问题,她表示之前都是泡面,没煮过面,所以不知道一次煮多久才能保证煮熟(不是生的也不煮糊)
so easy,我说,接下来就是体现面向对象的高端之处了。
因为之前20分钟煮糊了,所以在1~19分钟煮一分钟看一下面的状态就好
可是这怎么实现呢
如果你之前认真阅读并且有点小聪明,则应该看出来了吧
什么?你没看出么
好吧,我来详细分析一下:
我们之前累加了状态并且输出状态,当我们把19分钟划分为1分钟一次依次看泡面状态是不是就ok了
接下来撸起袖子干!
class Cook_instant_noodles:
def __init__(self):
self.cookedState = '生的'
self.cookedLevel = 0
def __str__(self):
return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
def cook(self,cooked_time):
self.cookedLevel += cooked_time
if cooked_time >= 0 and cooked_time < 3:
self.cookedState = '还没熟'
elif cooked_time >= 3 and cooked_time < 5:
self.cookedState = '半生不熟'
elif cooked_time >= 5 and cooked_time < 8:
self.cookedState = '煮熟了'
elif cooked_time >= 8:
self.cookedState = '煮糊了'
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()
print(instant_noodles)
#开始煮泡面
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
看晕了吧,我每次煮一分钟,看一下泡面状态。
我们看看结果
完了,又煮不熟了
回看程序,发现我们最后是不是应该根据总的累积cookedLevel判断状态,而不是一次的cooked_time
所以修改代码,将
中的cooked_time改为self.cookedLevel
class Cook_instant_noodles:
def __init__(self):
self.cookedState = '生的'
self.cookedLevel = 0
def __str__(self):
return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
def cook(self,cooked_time):
self.cookedLevel += cooked_time
if self.cookedLevel >= 0 and self.cookedLevel < 3:
self.cookedState = '还没熟'
elif self.cookedLevel >= 3 and self.cookedLevel < 5:
self.cookedState = '半生不熟'
elif self.cookedLevel >= 5 and self.cookedLevel < 8:
self.cookedState = '煮熟了'
elif self.cookedLevel >= 8:
self.cookedState = '煮糊了'
#创建了一个泡面对象
instant_noodles = Cook_instant_noodles()
print(instant_noodles)
#开始煮泡面
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
大功告成!通过观察结果,为了节约时间和煤气,5分钟就能煮好泡面。
粗心的小姐姐--吃面不加调料
小姐姐请我吃她煮的面
但我发现!尼玛,怎么没放调料。。。
她解释说,第一次,有点紧张
(旁白:前文说到过,小姐姐第一次煮泡面)
这就是你不放调料的理由???
好吧,我只能:
看来只能先上车后买票了
啊呸,是 先煮面后加调料
加调料怎么加,这是个问题。
我:先加什么,后加什么?
小姐姐:难道不是一次加进去的么,你当你吃拌面啊!?
小姐姐:
我:
小姐姐:
我:
于是需要将调料加到面里面:
调料作为一些值需要保存在变量里,在面向对象中,则是保存在属性里,又因为有很多种调料,所以我要找个能存放多种调料的容器
在这里我们选择list(列表)作为容器
在属性里定义一个空列表:
self.condiments = []#定义调料列表
定义一个加调料的方法:
def addCondiments(self,item):
#使用属性保存数据
self.condiments.append(item)
列表采用append()方法添加元素,这里的传进来的元素参数为item
由于要显示出状态中包含调料,所以要修改__str__()方法
def __str__(self):
return '泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
所以改完之后是这样的:
class Cook_instant_noodles:
def __init__(self):
self.cookedState = '生的'
self.cookedLevel = 0
self.condiments = []#定义调料列表
def __str__(self):
return '泡面状态:%s(%d)),添加的佐料有:%s'%(self.cookedState,self.cookedLevel,str(self.condiments))
def cook(self,cooked_time):
self.cookedLevel += cooked_time
if self.cookedLevel >= 0 and self.cookedLevel < 3:
self.cookedState = '还没熟'
elif self.cookedLevel >= 3 and self.cookedLevel < 5:
self.cookedState = '半生不熟'
elif self.cookedLevel >= 5 and self.cookedLevel < 8:
self.cookedState = '煮熟了'
elif self.cookedLevel >= 8:
self.cookedState = '煮糊了'
def addCondiments(self,item):
#使用属性保存数据
self.condiments.append(item)
注意:
这里的列表元素(调料)要转成字符串输出
下面,小姐姐开始煮第二碗面给她自己,第一碗面是之前忘加调料煮完的,我默默调料加进去了拌了拌。
#开始煮泡面
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.addCondiments('菜包')
instant_noodles.addCondiments('粉包')
instant_noodles.addCondiments('酱包')
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.addCondiments('冰箱里的茶叶蛋')
instant_noodles.addCondiments('冰箱里的火腿肠')
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
print(instant_noodles)
instant_noodles.cook(1)
小姐姐加的调料:
看到结果的我眼泪掉下来
小姐姐这套路可以的。。。
想继续边听讲故事边零基础学习Python面向对象编程么,请持续关注连载~
如果觉得《python面向对象编程从零开始_Python面向对象编程从零开始(4)—— 小姐姐请客下篇》对你有帮助,请点赞、收藏,并留下你的观点哦!