先来快速回顾一下上次的学习内容。
为了迎接今天的学习,咱们来简单做道练习题,热个身。
单选题
请你选出以下选项中错误的一项。
A.在为变量命名时,中间可以加空格。
B.运行print(‘一是’+str(1)),终端会显示结果一是1。
C.print(‘你好啊{}’.format(‘知枫’))的语法格式正确,运行结果是不会报错的。
解析:给变量命名的时候,中间是不可以加空格的。其中,B 选项中字符串拼接的 1 需要加上str()转为字符串的格式后是可以打出一是1的结果的。C 选项中字符串格式化用:format(),其有两种常见的用法,第一种用法中 format() 的参数会按照 {} 的位置顺序分别替换:
第二种用法则是按照标识,用值替换对应的替换字段:
回到这一题,用了按照位置顺序进行替换的方法,所以 format() 的参数'
知枫'
会被传入到第一个也是唯一一个 {} 中替换。这就是 format() 的用法。
答案:A
今天我们学习的内容是:类与函数。
虽然大部分时间,我会给你讲解类与函数背后的定义及原理。
但注意,你的学习重点在类与函数的调用方法上,即学会使用函数及类的方法。
这么安排,是因为我希望你不仅仅只是会用 Python 的一些语法,还能对 Python 有更深层次的理解,如此你会学得更扎实。
简单打个比方,一个优秀的赛车手不只是会开车而已,他往往还懂车本身的知识和原理。
1.类与对象(上):汽车蓝图
想象在编程宇宙中,你是一家汽车公司的实习生,为了更好地学习,那么第一步,你需要先看懂公司的汽车设计蓝图。
在编程宇宙的世界里,设计蓝图是以类的形式呈现的,所以在正式去看蓝图前,咱们需要先理解编程中的类与对象是什么。
1.1 类与对象
1.1.1 类
听到类与对象,很多同学容易想太多,想得太复杂与抽象,但事实上这并不是一个复杂的概念。
先不管 Python 里的类。在日常生活中,你可能会出现这样的对话:“这一类面包真的好难吃”、“这一类蔬菜都对身体很好”。
这里的“类”你应该都能理解吧,它的意思是对一类事物的概括。
而这些被概括的事物,虽然它们可能各不相同,但却往往有着一些共同的特征,例如:都难吃,都对身体好等。
再举个简单的例子,车是一类物件。
虽然每辆车都有各自不同的地方,如颜色不同、大小不同等,但它们的一些共同特征(例如:有轮子,能跑等)决定了它们都属于车这一类。
当然,只要我想,我还可以举出无限的例子。
环顾四周,事实上我们知道的所有事物几乎都被人类划分成了各个类,如食物、电子产品、健身器材、交通工具等等。
那回到 Python 里,编程里说的类是什么呢?它和生活中其实是一样的。
比如,1、2、3、4 这些数据都属于整数(int)一类;虽然值各不一样,但都有能进行加减运算等的相同点。
‘1’、‘2’、‘3’、‘4’,这些数据都属于字符串(str)这一类;虽然值各不一样,但都有能进行拼接等的相同点。
来串代码看看,你阅读完代码后,本地直接运行即可:
# 1、2、3 属于整数(int)类
print(type(1))
print(type(2))
print(type(3))
# '1'、'2'、'3' 属于字符串(str)类
print(type('1'))
print(type('2'))
print(type('3'))
可以看到,终端显示的结果为:<class ‘int’>、<class ‘str’>。class 在英文中是“类别”的意思,在编程中就代表类。
这就表明它们虽各自值不同,但都分别属于整数(int)类、字符串(str)类。
1.1.2 对象
聊完了类,那对象是什么?
刚刚说到,类是对一类事物的概括/抽象。那么反过来,这类东西里每一个单独的个体就属于对象。
再回到车的例子,虽然每辆车不同,但是都属于车这一类,但每辆不同的车就是一个个不同的对象。
比如,小明骑的单车、和小明爸爸驾驶的小轿车,就是两个不同的对象。
来道选择题,试试看你是否能理解类与对象的差别。
单选题
以下描述中,哪个“车”是对象?
A.车都开得挺快的
B.你家的车擦得真干净
解析:A 选项的车是对所有车的特征的概括,所以是类。B 选项的车特指你家的车,是车类中的一个对象。
那么回到 Python 中,也是类似的,比如:1、 2都属于一个类:整数(int),但 1 和 2 是两个不同的对象。
那类有什么用呢?对我们编程又有什么帮助?
1.1.3 类的作用
它在编程里的作用与我们人类社会的工业化生产是类似的,这里以汽车的生产为例。
众所周知,每款汽车都有各自的设计蓝图,这个设计蓝图类比到编程中就像是类,它决定了这类型/款式/型号的汽车应该有什么一致的特征,并以此为生产标准规范。
而对象,就像一辆根据设计图生产出来的汽车。
虽然我们开的是汽车、用的是对象,但蓝图可用于指导批量生产汽车、类也可以作为模板批量生成对象,类与蓝图让这一切变得更加高效规范。
所以,光有蓝图虽不能开车,但并不代表蓝图就没有用。
如果没有蓝图的话,就相当于每一辆车都要重新设计后再投入生产。这样生产效率将大打折扣。
就像原始部落的人与工厂流水线的人比赛造车,从效率角度出发,这是完全没有可比性的。
就像蓝图能指导汽车生产一样,Python 中类能实例化产生对象。
这里实例化的意思是:根据类产生一个实际的对象。
等会我们将会逐步完善一个用类装载的汽车“蓝图” demo,并用这个“蓝图”实例化一个汽车“对象”,用于学习它的使用方法。
怎么样?迫不及待了,让我们回到 Python 中,看看这张“蓝图”的类具体长什么样吧。
1.2 类的结构
要想看 Python 中的类长什么样,就要从它的起点开始拆解,也就是从类的定义开始。
先简单地写下它的语法结构:
class 类名:代码块
从语法上来看:类的定义是一个 class 语句,class 语句内包含了四个要素:
① 关键字"class";② 类名;③ 英文冒号":";④ 代码块(即类里面的代码内容)。
其中,规范要求类名的首字母应是大写。与if条件判断语句一样,代码块前方要注意缩进。
1.3 类的属性和方法
从汽车蓝图的角度出发,我们可以从两个方面来描述一辆车:
一、汽车的状态怎样?包括车的颜色(color)、大小(shape)等;
二、它能做什么?如:向前开(drive)、刹车(stop)、漂移(skr);
那么在 Python中也是一样,对这个类 Cars 来说:它的状态怎样,存储了什么数据,就是类的属性;
它能做什么?就是类的方法。一个个来,先看属性。
在本案例中,类的属性就是定义在类中的变量,如下面这串代码:
# 定义一个车类 Cars
class Cars:
# 属性(外形构造)
color = '黑'
shape = '小'
如以上代码:像 color、shape 这些在类中被定义的变量,就是类 Cars 中构造的属性。
它们的定义语法也很简单,直接在类中对一个变量赋值就好了。这样,我们就相当于在这张类的汽车蓝图里设定这辆车被生产出来后的状态。
那么聊完了属性,接下来就到类的方法了。
简单来说,在类中被定义的函数就是类的方法。所以要理解清楚类的方法,你就需要先学习一个新知识:函数
。
每个函数会实现特定的功能,将一个个函数组合在一起,就实现了这个类它能做的所有事情。类比到汽车中,一个函数就像一个汽车零部件,它会负责实现它所对应的功能,如:前进、刹车、漂移等功能。
在函数这里,我们会学习它的定义过程、运行流程、及参数的概念,以及如何去调用函数;
讲完函数以后,我们会再回到类的方法来,到时候你理解起来就会简单许多。
2. 函数:定制汽车功能
在 Python 中,函数是组织好的,可以重复使用,用来实现某一功能的代码。
通过把代码打包起来使用,函数能有效减少重复性代码。它们就像一个个精巧设计的仪器,让你更方便地实现某些功能。
如在 Python 里面替你打包好的内置函数:input()、print(),它就能帮你打印、从终端采集信息。
你可能已经习惯了调用 Python 的内置函数,没有感觉到什么便利之处。但事实上,它们在很多看不到的地方已经节省了你非常多的时间。
那除了 input()、print()…这些内置函数,我们总会需要内置函数满足不了的功能,这时又该怎么办呢?
同类的定义一样,我们可以定义一个函数,为我们的汽车定制一个功能。
2.1 函数的定义
定义函数,就是自定义一个属于自己的函数,它的语法格式如下:
def 函数名(参数):
代码块
咱们一个个来看,首先看到def:
定义函数时,我们要用到def语句,def 在英文中是 define 的缩写,意为“定义”,为定义函数的固定格式。
然后看到函数名:
和类的定义语法一样,这里的函数名也是自己命名的,如汽车蓝图中的函数:
# 实现前进功能的零部件(函数):drivedef drive():
print('一辆黑色的小汽车快速向前开')
# 实现刹车功能的零部件(函数):stop
def stop():
print('一辆黑色的小汽车停车')
# 实现漂移功能的零部件(函数):skr
def skr():
print('一辆黑色的小汽车快速漂移')
负责前进功能的零部件(函数)叫:drive()。而除了 drive() 以外的其它零部件(函数)也都有其需要实现的功能,就像:
stop() 负责刹车,skr() 负责漂移。
而这里每个零件(函数)都有它们唯一固定的名称(函数名),它们也都可以处理一定的数据(参数)等。
这里的参数是函数要接收并对其进行处理的数据。
定义函数时,你可以像上面的代码一样不设置参数,但也可以设置很多个参数,关于它等会我们会细讲。
最后是代码块:
代码块就是函数内的代码内容,用于实现函数功能。当你使用函数时,就会执行代码块内的内容。
先讲不设置参数时的情况,这里拆解一个咱们汽车蓝图中的零部件函数:drive() 来看。
在这段代码中:
函数名为:drive
代码块内容为:print(‘一辆汽车向前开’)
阅读完本地直接运行下列代码即可:
def drive():
print('一辆汽车向前开')
运行代码后为何没反应呢?按理来说应该已经成功定义这个函数了呀。
这是因为你还没有调用函数,调用函数就是我们常说的使用函数的功能,函数需要调用才能发挥作用。
就像有了仪器,有了汽车,也需要先启动使用才能发挥它的功能。
回到 Python 中来,没设置参数时,调用函数的语法是:函数名()
。调用函数以后,函数内的代码块就会自动执行。再试着运行下面这段代码,注意看最后一行代码:
# 定义函数
def drive():
print('一辆汽车向前开')
# 调用函数
drive()
看到代码块的内容被运行成功了吗?如果没问题的话,你就成功调用了这个你定义的函数。
2.2 函数的执行流程
那么你可能会有疑问,刚刚的那个函数是怎么执行的?一个函数的执行顺序又应该是怎样的呢?
还是刚刚那段代码,阅读完直接本地运行就好了。
# 定义函数名为drive
def drive():
print('我在最后被打印')
print('我会先被打印')
# 调用函数
drive()
看到终端显示的结果,正如我们前面所讲的,调用函数以后才会执行函数内部的代码块。
调用函数的代码在第 7 行,所以第 5 行代码先被打印了出来,然后才轮到函数内代码块的内容被打印出来。
需要注意的是:如果没有定义过函数就对其调用,会出现报错的,接下来考考你,来看看下面这串代码:
drive()
# 定义函数名为drive
def drive():
print('一辆黑色的汽车向前开')
从函数的运行流程的角度出发,你觉得代码运行后会报错吗?
会,因为还未定义函数就进行调用,所以会报错。
咱们来运行一下刚刚那段代码看看
drive()
# 代码会报错
# 定义函数名为drive
def drive():
print('一辆黑色的汽车向前开')
相信你已经明白函数的代码执行流程了,最后用一张图做个总结:
2.3 参数
在汽车的功能使用中,我们会希望能更好地控制它的功能,例如:我们不希望车子是一直匀速向前开的,有时希望能开快点,有时又希望能开慢点。
同样,在编程宇宙中驾驶汽车,要想做到控制汽车的各个零部件(函数)的功能,我们就需要学习一个新知识:参数。
回顾一下定义函数的语法格式:
def 函数名(参数):
代码块
在 Python 中,参数是函数要接收并对其进行处理的数据。
下面我升级了一下drive()函数的功能,使其能根据输入的参数(speed)打印出不同的语句。
咱们直接从代码来看,Python 是如何通过参数传递的数据来执行函数内的代码块的吧。
刚刚我们调用的函数只有一个参数,那当有多个参数时该怎么办呢?
定义函数时,设置多个参数的语法一般为:
def 函数名(参数, 参数....):
代码块
在这些参数里,我们比较常用的参数类型是位置参数,来看:
3. 类与对象(下):把车开起来
如此一来,我们就学习完了函数,相信你也掌握了用函数定制并控制单个汽车功能的方法。
那么现在回到蓝图中来看,我们把零部件(函数)组装在一起就变成了汽车的动力、操作系统(类的方法)。
从 Python 的角度来说,一般情况下,我们把函数放进类中定义就变成类的方法了。
3.1 类的方法定义语法
回到 Python 中类的方法,咱们来看它的语法格式:
class 类名:
def 方法名(self, 参数...):
代码块
事实上就是在定义类的时候,在类内部的代码块再定义一个函数。
可以看到这里多了一个self 参数,它用来指对象本身。
一般在类中定义方法第一个参数都是 self 参数,这背后涉及的原理较多,你可以当作一个固定格式。
咱们回到汽车设计蓝图的代码来看:
# 定义一个车类 Cars
class Cars:
# 方法 (动力、操作系统)
def drive(self):
print('一辆黑色的小汽车快速向前开')
def stop(self):
print('一辆黑色的小汽车停车')
def skr(self):
print('一辆黑色的小汽车快速漂移')
这里解释起来就很简单啦,这里定义了三个类的方法(drive、stop、skr),也就是三个在类中定义的函数。
它们分别实现了这辆汽车的:前进、停车、漂移,三个功能。学会调用这些类的方法,就能把汽车开起来了!
诶,不对不对,咱们现在还只是在蓝图上“纸上谈兵”呀,得有一架“真实”的汽车,才能开起来。
那我们该怎么根据现有的蓝图(类)生产一辆真正的汽车对象呢?
3.2 类的实例化(上)
这就涉及到了类的实例化的过程,实例化即根据类生成一个实际的对象。
我们直接从代码来看是怎么实现实例化的吧。
现在我们终于可以开动汽车了,这里是学习的重点了,要认真听哦。
3.3 类的属性、方法调用
等会等会,差点忘记了,为了保证安全,开车前,我们要先检查车身状态。
此时你就需要调用类的属性,即提取车的状态(外形构造)信息,车的颜色(color)、大小(shape)。
调用类的属性语法格式如下:
对象.属性
回到实际代码中来看,类的属性调用后有什么效果,阅读完代码后本地运行即可:
# 定义一个车类 Cars
class Cars:
# 属性(外形构造)
color = '黑'
shape = '小'
# 实例化对象
car = Cars()
# 调用属性并打印查看
print(car.color)
print(car.shape)
例如这里的car.color调用了类 Cars 中的属性 color,值为’黑’。
car.shape调用了类 Cars 中的属性shape,值为’小’。
然后打印就可以在终端查看对应的属性值。
现在看来车子外表没问题了,那类的方法又该怎么调用呢?怎么让车动起来呢?就不卖关子了,语法格式如下:
对象.方法名(值,...)
咱们直接从实际的代码来看,先看无需输入参数值到函数时该如何调用类的方法,重点看最后一行,阅读完代码后本地运行:
# 定义一个车类 Cars
class Cars:
# 方法 (动力、操作系统)
def drive(self):
print('一辆黑色的小汽车快速向前开')
def stop(self):
print('一辆黑色的小汽车快速停车')
def skr(self):
print('一辆黑色的小汽车快速漂移')
car = Cars()
car.drive()
可能你会有疑问,为什么参数 self 不需要传入值呢?
因为这里参数 self 代表着对象本身。在你调用类的方法时忽略它即可,不用给 self 传参。
3.4 __init__()方法
如此一来,学会了调用类的方法及属性,我们就已经能够检查及驾驶汽车了。
但咱们继续拓展一下,不知你是否有发现,为啥咱们“蓝图”产出的车子都长一样呢?
我们是否可以优化一下“蓝图”,让“蓝图”能实现自由定制车型的功能?比如:在实例化时,可以设置汽车对象的 color 属性为’红’,也可以是’黑’,而不是每一种颜色的汽车都要重新建一个类。
答案当然是肯定的,类似于函数,在类里,我们可以在实例化时传入不同参数来生成不同属性的对象。
此时要用到类里面的一个特殊方法:__init__()方法。
__init__()方法也叫初始化方法,类在实例化时,__init__()方法会自动运行内部的代码。
直接来看一段代码,运行查看结果:
# 定义一个类 Test
class Test:
# 初始化方法
def __init__(self):
# 如果实例化成功,下面这句将会被打印出来。
print('一旦实例化以后,我会被自动执行。')
# 实例化类 Test
a = Test()
可以看到当你实例化了类 Test 时,__init__()方法内的内容被自动执行了。
这是因为初始化方法会自动运行内部的代码,所以一旦实例化,print() 语句被执行,print() 语句的内容也就会被打印出来。
定义初始化方法的语法格式与其它类的方法的定义是相同的,但要注意的是:init前后需要加上两条下划线。
你可能此时会有疑问,这只是一个能够自动执行的方法,和类的属性又有什么关系呢?现在还是无法实现初始化方法实例化时就能让对象的 color 属性为’红’的需求,还是无法自由定制车型。
答案是:我们可以利用__init__()方法来定义类的属性。
3.5 类的实例化(下)
我们可以利用__init__()方法往类内部传入参数,来为类灵活地设置属性。
4. 总结与练习
4.1 知识总结
今天主要学习了类与函数,下面是知识总结图:
接下来对本关的学习重点做一下梳理。
一、函数的调用
函数的调用就是使用函数,它的语法格式是:
函数名(参数值...)
二、参数
参数是函数要接收并对其进行处理的数据;
其中,参数里面位置参数最为常见:
位置参数即:按照对应参数的位置顺序进行传递的参数。
# 定义函数时,设置三个参数shape, speed, color
def drive(color, shape, speed):
在上面的代码中,shape、speed、color就是位置参数。
三、类的实例化
根据类生成对象即类的实例化,它的语法格式为:
对象 = 类名(值, ...)
四、类的方法、属性调用
类的方法调用语法格式如下:
对象.方法名()
类的属性的调用语法格式如下:
对象.属性
这样我们就梳理完本节的知识点啦,最后做几道练习巩固一下吧。
4.2 练习
【代码练习】调用函数,要求能打印出:“车速满足要求,这辆黑色的汽车可以开进高速公路”。
【温馨提示】高速公路要求:速度参数 speed 在 60 到 120 之间。
# 定义函数drive
def drive(color, speed):
if 60 <= speed <= 120:
print('车速满足要求,这辆{}色的汽车可以开进高速公路'.format(color))
else:
print('禁止通行')
# 调用函数并输入对应的参数值
怎么样?打印结果正确吗?以下是我的答案:
# 定义函数drive
def drive(color, speed):
if 60 <= speed <= 120:
print('车速满足要求,要求这辆{}色的汽车可以开进高速公路'.format(color))
else:
print('禁止通行')
# 调用函数并输入对应的参数值
drive('黑', 100)
今天的学习内容到这里就结束啦,为你的坚持鼓个掌吧。加油,基础阶段也快结束了,期待你学习完成,可以继续下一个阶段内容的学习。