在上一篇《手把手陪您学Python》41——类方法与实例方法中,我们引入了类方法的概念,并介绍了类方法与实例方法在语法规则和引用方面的差异。今天,我们将会继续介绍实例方法的应用,并介绍一种非常重要而又特殊的实例方法。
1、通过实例方法定义实例属性
在《手把手陪您学Python》40——类的定义、属性与实例化中,我们曾介绍过实例属性,是指通过给实例变量赋值,定义的只属于实例的而不属于类的属性。今天我们将会介绍一种新的定义实例属性的方法,就是通过实例方法来定义实例属性。
由于方法本身就比属性能够做更多的“事情”,所以通过实例方法定义的实例属性不但能够达到通过变量定义属性一样的效果,还具有更为强大的功能,实现更加灵活的人机互动。
像我们小时候玩超级玛丽总是觉得不过瘾,3条命根本不够通关的,要是能像魂斗罗一样,可以有30条命就好了。这时,我们就可以通过定义实例方法的方式来达到这样的目的。
第一种方式是实例方法中不包括参数。在实例方法里给实例属性赋值,也就是马里奥的生命值以及帽子的颜色已经在实例方法中确定了。当引用实例方法时,已经定义好的实例属性生效。
In [1]: class Mario:
def star(self):
self.life = 30 # 实例属性已经在实例方法中定义
self.cap = "blue"
In [2]: small_mario = Mario()
small_mario.star() # 只引用实例方法,实例属性已经在实例方法中确定
print(small_mario.life)
print(small_mario.cap)
Out[2]: 30
blue
第二种方式是实例方法中包括参数。在定义实例方法时,将实例属性的值作为实例方法的参数,在引用实例方法时,同时定义实例属性的值,也就是在实例化马里奥后确定生命值以及帽子的颜色了。
In [3]: class Mario:
def star(self, life, cap): # 实例属性的值作为实例方法的参数
self.life = life
self.cap = cap
In [4]: small_mario = Mario()
small_mario.star(30, "blue") # 引入实例方法的同时定义实例属性
print(small_mario.life)
print(small_mario.cap)
Out[4]: 30
blue
通过实例方法,让我们可以定义各种类型的实例属性,但是先是实例化,再通过引用实例方法定义实例属性的过程还是有些繁琐,有没有更简单的定义实例属性的方法呢,比如在实例化的过程中就直接定义好实例属性?答案是肯定的,这就是__init__()方法。
2、__init__()方法
__init__()方法是一种称之为“构造器”的特殊的实例方法。在创建实例的时候,即使不去引用__init__()方法,其中的命令也会自动执行。
如果__init__()方法是带有参数的,那么在类的实例化过程中,参数可以通过__init__()方法自动传递给实例。就可以不用先引用实例方法再给实例属性赋值了,实现了“一步到位”,是不是非常的神奇?所以,__init__()方法也经常被称为“魔法方法”。
与之前相同的是,也可以将__init__()方法中是否包括参数,将定义实例属性的方式分为两类。
与之前不同的是,由于__init__()方法能够自动执行,所以不需要再引用__init__()方法(也无法引用),而是在实例化马里奥时,同时完成了实例方法的引用,实例方法中已经确定的实例属性也就自动生效了(第一种方式);或者在实例化马里奥的同时定义实例属性的值(第二种方式)。
In [5]: class Mario:
def __init__(self):
self.life = 30 # 实例属性已经在实例方法中定义
self.cap = "blue"
In [6]: small_mario = Mario() # 实例化的同时实例方法执行,实例属性生效
print(small_mario.life)
print(small_mario.cap)
Out[6]: 30
blue
In [7]: class Mario:
def __init__(self, life, cap): # 实例属性的值作为实例方法的参数
self.life = life
self.cap = cap
In [8]: small_mario = Mario(30, "blue") # 实例化的同时给实例属性赋值
print(small_mario.life)
print(small_mario.cap)
Out[8]: 30
blue
上面的例子中,我们将马里奥的生命值和帽子颜色或者是在实例方法中已经定义好,或者是在实例化的同时进行定义,但这两种方式都已经在程序中写死。如果我们在实例方法里或者实例化前,通过人机互动的方式,将定义实例属性的权利交给用户,就可以让用户自由定义生命值和帽子颜色了。
In [9]: class Mario:
def __init__(self):
number = input("请输入马里奥的生命值:")
colour = input("请输入马里奥帽子的颜色:")
self.life = number # 实例属性已经在实例方法中定义
self.cap = colour
In [10]: small_mario = Mario() # 实例化的同时实例方法执行,实例属性生效
print(small_mario.life)
print(small_mario.cap)
Out[10]: 请输入马里奥的生命值:30请输入马里奥帽子的颜色:blue
30
red
In [11]: class Mario:
def __init__(self, life, cap): # 实例属性的值作为实例方法的参数
self.life = life
self.cap = cap
In [12]: number = input("请输入马里奥的生命值:")
colour = input("请输入马里奥帽子的颜色:")
small_mario = Mario(number, colour) # 实例化的同时给实例属性赋值
print(small_mario.life)
print(small_mario.cap)
Out[12]: 请输入马里奥的生命值:30
请输入马里奥帽子的颜色:blue
30
red
3、其他魔法方法的应用
由于__init__()方法能够自动执行,所以除了能够自动执行__init__()方法下的语句,还可以引用其他实例方法或者属性,而无需人工引用,大大增加了程序的自动运行效率。
比如,我们可以让马里奥一出场就蹦蹦跳跳地,刚吃完蘑菇就打败了一个敌人。
In [13]: class Mario:
def __init__(self, life, cap, name, food):
self.life = life
self.cap = cap
print("{} has {} lifes.".format(name, self.life))
print("{} has a {} cap.".format(name, self.cap))
self.jump()
self.eat(name, food)
self.attack(name)
def jump(self):
print("Mario is jumping!")
def attack(self,name):
print("{} attacked an anomy!".format(name))
def eat(self, name, food):
print("Mario ate a {}!".format(food))
print("{} became bigger!".format(name))
In [14]: small_mario = Mario(30, "red", "Small Mario", "red mushroom")
Out[14]: Small Mario has 30 lifes.
Small Mario has a red cap.
Mario is jumping!
Small Mario ate a red mushroom!
Small Mario became bigger!
Mario attacked an anomy!
以上就是我们的通过实例方法定义实例属性的介绍,同时还对魔法方法的使用进行了重点说明。
下一篇,我们将会进一步学习类的知识,包括类的继承与魔法方法的其他应用,敬请关注。
感谢阅读本文!如有任何问题,欢迎留言,一起交流讨论^_^
要阅读《手把手陪您学Python》系列文章的其他篇目,请关注公众号点击菜单选择,或点击下方链接直达。
《手把手陪您学Python》3——PyCharm的安装和配置
《手把手陪您学Python》5——Jupyter Notebook
For Fans:关注“亦说Python”公众号,回复“手42”,即可免费下载本篇文章所用示例语句。
