Python面向对象编程从零开始(4)—— 小姐姐请客下篇

浏览: 4345

前言

前文传送门:

Python面向对象编程从零开始(1)——从没对象到有对象:https://ask.hellobi.com/blog/wangdawei/8429

Python面向对象编程从零开始(2)—— 与对象相互了解:https://ask.hellobi.com/blog/wangdawei/8446

Python面向对象编程从零开始(3)—— 小姐姐请客上篇:https://ask.hellobi.com/blog/wangdawei/8463

分割线---------------------------------------------------------------------------------------------------------------------------

又到了新的一周,继续连载啊,哈哈

上次故事说到小姐姐请我吃大(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分钟,还是生的

泡面煮不熟的原因竟然是

原因在于:

Clipboard Image.png

程序执行的流程可以理解为这样:

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)

Clipboard Image.png

面临新问题,接受挑战!

观察结果,虽然第二次煮了20分钟煮糊了,状态得到改变了,但是,时间却还是显示0分钟,这是为什么呢?

我们回看代码:

Clipboard Image.png

我们在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)

Clipboard Image.png


这下,问题总算是解决了

小姐姐的新困扰--宝宝没煮过面啊

虽然煮面功能完成了,但是小姐姐提出了新问题,她表示之前都是泡面,没煮过面,所以不知道一次煮多久才能保证煮熟(不是生的也不煮糊)

so easy,我说,接下来就是体现面向对象的高端之处了。

因为之前20分钟煮糊了,所以在1~19分钟煮一分钟看一下面的状态就好

可是这怎么实现呢

如果你之前认真阅读并且有点小聪明,则应该看出来了吧

什么?你没看出么

好吧,我来详细分析一下:

我们之前累加了状态并且输出状态,当我们把19分钟划分为1分钟一次依次看泡面状态是不是就ok了

接下来撸起袖子干!


Clipboard Image.png

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)

看晕了吧,我每次煮一分钟,看一下泡面状态。

我们看看结果

Clipboard Image.png

完了,又煮不熟了

回看程序,发现我们最后是不是应该根据总的累积cookedLevel判断状态,而不是一次的cooked_time

所以修改代码,将

Clipboard Image.png

中的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)

Clipboard Image.png

大功告成!通过观察结果,为了节约时间和煤气,5分钟就能煮好泡面。

粗心的小姐姐--吃面不加调料

小姐姐请我吃她煮的面

但我发现!尼玛,怎么没放调料。。。


Clipboard Image.png

她解释说,第一次,有点紧张

(旁白:前文说到过,小姐姐第一次煮泡面)

这就是你不放调料的理由???

好吧,我只能:

Clipboard Image.png


看来只能先上车后买票了

啊呸,是 先煮面后加调料

Clipboard Image.png

加调料怎么加,这是个问题。

我:先加什么,后加什么?

小姐姐:难道不是一次加进去的么,你当你吃拌面啊!?

小姐姐: Clipboard Image.png

我: Clipboard Image.png

小姐姐: Clipboard Image.png

我: 

于是需要将调料加到面里面:

调料作为一些值需要保存在变量里,在面向对象中,则是保存在属性里,又因为有很多种调料,所以我要找个能存放多种调料的容器

在这里我们选择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)

注意:Clipboard Image.png

这里的列表元素(调料)要转成字符串输出

下面,小姐姐开始煮第二碗面给她自己,第一碗面是之前忘加调料煮完的,我默默调料加进去了拌了拌。


#开始煮泡面
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)

小姐姐加的调料:

Clipboard Image.png

看到结果的我眼泪掉下来

小姐姐这套路可以的。。。

Clipboard Image.png


想继续边听讲故事边零基础学习Python面向对象编程么,请持续关注连载~

推荐 4
本文由 ID王大伟 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

4 个评论

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,cook_time):
self.cookedLevel+=cook_time
if cook_time>=0 and cook_time<3:
self.cookedState='生的'
elif cook_time>=3 and cook_time<5:
self.cookedState='还没熟'
elif cook_time>=5 and cook_time<8:
self.cookedState ='熟了'
elif cook_time>=8:
self.cookedState='糊了'

instant_noodles = cook_instant_noodles()

print(instant_noodles)
instant_noodles.cook(20)

print(instant_noodles)





——————————————————————————————————————

<__main__.cook_instant_noodles object at 0x000000D757185B70>




---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-23-5b0fe5f3549e> in <module>()
19
20 print(instant_noodles)
---> 21 instant_noodles.cook(20)
22
23 print(instant_noodles)

<ipython-input-23-5b0fe5f3549e> in cook(self, cook_time)
6 return'泡面状态:%s(%d)'%(self.cookedState,self.cookedLevel)
7 def cook(self,cook_time):
----> 8 self.cookedLevel+=cook_time
9 if cook_time>=0 and cook_time<3:
10 self.cookedState='生的'

AttributeError: 'cook_instant_noodles' object has no attribute '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,cook_time):
self.cookedLevel+=cook_time
if cook_time>=0 and cook_time<3:
self.cookedState='生的'
elif cook_time>=3 and cook_time<5:
self.cookedState='还没熟'
elif cook_time>=5 and cook_time<8:
self.cookedState ='熟了'
elif cook_time>=8:
self.cookedState='糊了'

instant_noodles = cook_instant_noodles()

print(instant_noodles)
instant_noodles.cook(20)

print(instant_noodles)
小姐姐我的问题已经解决了
在同一个类中的方法之间,有么有执行的优先级

要回复文章请先登录注册