python第十三课 函数(二)

"魔法"方法

1. 打印id()

如果把BMW使用print进行输出的话,会看到如下的信息

即看到的是创建出来的BMW对象在内存中的地址

2. 定义__str__()方法

classCar:

def__init__(self, newWheelNum, newColor):

self.wheelNum = newWheelNum

self.color = newColor

def__str__(self):

msg ="嘿。。。我的颜色是"+ self.color +"我有"+str(self.wheelNum) +"个轮胎..."

returnmsg

defmove(self):

print('车在跑,目标:夏威夷')

BMW = Car(4,"白色")

print(BMW)

总结

在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法

当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据

self

1. 理解self

看如下示例:

# 定义一个类

classAnimal:

# 方法

def__init__(self, name):

self.name = name

defprintName(self):

print('名字为:%s'%self.name)

# 定义一个函数

defmyPrint(animal):

animal.printName()

dog1 = Animal('西西')

myPrint(dog1)

dog2 = Animal('北北')

myPrint(dog2)

运行结果:

总结

所谓的self,可以理解为自己

可以把self当做C++中类里面的this指针一样理解,就是对象自身的意思

某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可

应用:烤地瓜

为了更好的理解面向对象编程,下面以“烤地瓜”为案例,进行分析

1. 分析“烤地瓜”的属性和方法

示例属性如下:

cookedLevel : 这是数字;0~3表示还是生的,超过3表示半生不熟,超过5表示已经烤好了,超过8表示已经烤成木炭了!我们的地瓜开始时时生的

cookedString : 这是字符串;描述地瓜的生熟程度

condiments : 这是地瓜的配料列表,比如番茄酱、芥末酱等

示例方法如下:

cook(): 把地瓜烤一段时间

addCondiments(): 给地瓜添加配料

__init__(): 设置默认的属性

__str__(): 让print的结果看起来更好一些

2. 定义类,并且定义__init__()方法

#定义`地瓜`类classSweetPotato:

'这是烤地瓜的类'

#定义初始化方法

def__init__(self):

self.cookedLevel =

self.cookedString ="生的"

self.condiments = []

3. 添加"烤地瓜"方法

#烤地瓜方法

defcook(self, time):

self.cookedLevel += time

ifself.cookedLevel >8:

self.cookedString ="烤成灰了"

elifself.cookedLevel >5:

self.cookedString ="烤好了"

elifself.cookedLevel >3:

self.cookedString ="半生不熟"

else:

self.cookedString ="生的"

4. 基本的功能已经有了一部分,赶紧测试一下

把上面2块代码合并为一个程序后,在代码的下面添加以下代码进行测试

mySweetPotato = SweetPotato()

print(mySweetPotato.cookedLevel)

print(mySweetPotato.cookedString)

print(mySweetPotato.condiments)

完整的代码为:

classSweetPotato:

'这是烤地瓜的类'

#定义初始化方法

def__init__(self):

self.cookedLevel =

self.cookedString ="生的"

self.condiments = []

#烤地瓜方法

defcook(self, time):

self.cookedLevel += time

ifself.cookedLevel >8:

self.cookedString ="烤成灰了"

elifself.cookedLevel >5:

self.cookedString ="烤好了"

elifself.cookedLevel >3:

self.cookedString ="半生不熟"

else:

self.cookedString ="生的"

# 用来进行测试

mySweetPotato = SweetPotato()

print(mySweetPotato.cookedLevel)

print(mySweetPotato.cookedString)

print(mySweetPotato.condiments)

5. 测试cook方法是否好用

在上面的代码最后面添加如下代码:

print("------接下来要进行烤地瓜了-----")

mySweetPotato.cook(4)#烤4分钟

print(mySweetPotato.cookedLevel)

print(mySweetPotato.cookedString)

6. 定义addCondiments()方法和__str__()方法

def__str__(self):

msg = self.cookedString +" 地瓜"

iflen(self.condiments) >:

msg = msg +"("

fortempinself.condiments:

msg = msg + temp +", "

msg = msg.strip(", ")

msg = msg +")"

returnmsg

defaddCondiments(self, condiments):

self.condiments.append(condiments)

7. 再次测试

完整的代码如下:

classSweetPotato:

"这是烤地瓜的类"

#定义初始化方法

def__init__(self):

self.cookedLevel =

self.cookedString ="生的"

self.condiments = []

#定制print时的显示内容

def__str__(self):

msg = self.cookedString +" 地瓜"

iflen(self.condiments) >:

msg = msg +"("

fortempinself.condiments:

msg = msg + temp +", "

msg = msg.strip(", ")

msg = msg +")"

returnmsg

#烤地瓜方法

defcook(self, time):

self.cookedLevel += time

ifself.cookedLevel >8:

self.cookedString ="烤成灰了"

elifself.cookedLevel >5:

self.cookedString ="烤好了"

elifself.cookedLevel >3:

self.cookedString ="半生不熟"

else:

self.cookedString ="生的"

#添加配料

defaddCondiments(self, condiments):

self.condiments.append(condiments)

# 用来进行测试

mySweetPotato = SweetPotato()

print("------有了一个地瓜,还没有烤-----")

print(mySweetPotato.cookedLevel)

print(mySweetPotato.cookedString)

print(mySweetPotato.condiments)

print("------接下来要进行烤地瓜了-----")

print("------地瓜经烤了4分钟-----")

mySweetPotato.cook(4)#烤4分钟

print(mySweetPotato)

print("------地瓜又经烤了3分钟-----")

mySweetPotato.cook(3)#又烤了3分钟

print(mySweetPotato)

print("------接下来要添加配料-番茄酱------")

mySweetPotato.addCondiments("番茄酱")

print(mySweetPotato)

print("------地瓜又经烤了5分钟-----")

mySweetPotato.cook(5)#又烤了5分钟

print(mySweetPotato)

print("------接下来要添加配料-芥末酱------")

mySweetPotato.addCondiments("芥末酱")

print(mySweetPotato)

隐藏数据

可能你已经意识到,查看过着修改对象的属性(数据),有2种方法

1. 直接通过对象名修改

SweetPotato.cookedLevel =5

2. 通过方法间接修改

SweetPotato.cook(5)

分析

明明可以使用第1种方法直接修改,为什么还要定义方法来间接修改呢?

至少有2个原因:

如果直接修改属性,烤地瓜至少需要修改2部分,即修改cookedLevel和cookedString。而使用方法来修改时,只需要调用一次即可完成

如果直接访问属性,可能会出现一些数据设置错误的情况产生例如cookedLevel = -3。这会使地瓜比以前还生,当然了这也没有任何意义,通过使用方法来进行修改,就可以在方法中进行数据合法性的检查

应用:存放家具

#定义一个home类classHome:

def__init__(self, area):

self.area = area#房间剩余的可用面积

#self.light = 'on' #灯默认是亮的

self.containsItem = []

def__str__(self):

msg ="当前房间可用面积为:"+ str(self.area)

iflen(self.containsItem) >:

msg = msg +" 容纳的物品有: "

fortempinself.containsItem:

msg = msg + temp.getName() +", "

msg = msg.strip(", ")

returnmsg

#容纳物品

defaccommodateItem(self,item):

#如果可用面积大于物品的占用面积

needArea = item.getUsedArea()

ifself.area > needArea:

self.containsItem.append(item)

self.area -= needArea

print("ok:已经存放到房间中")

else:

print("err:房间可用面积为:%d,但是当前要存放的物品需要的面积为%d"%(self.area, needArea))

#定义bed类classBed:

def__init__(self,area,name ='床'):

self.name = name

self.area = area

def__str__(self):

msg ='床的面积为:'+ str(self.area)

returnmsg

#获取床的占用面积

defgetUsedArea(self):

returnself.area

defgetName(self):

returnself.name

#创建一个新家对象

newHome = Home(100)#100平米

print(newHome)

#创建一个床对象

newBed = Bed(20)

print(newBed)

#把床安放到家里

newHome.accommodateItem(newBed)

print(newHome)

#创建一个床对象

newBed2 = Bed(30,'席梦思')

print(newBed2)

#把床安放到家里

newHome.accommodateItem(newBed2)

print(newHome)

总结:

如果一个对象与另外一个对象有一定的关系,那么一个对象可用是另外一个对象的属性

思维升华:

添加“开、关”灯,让房间、床一起亮、灭

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180419G1VSVV00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券