在上一篇《手把手陪您学Python》25——列表推导式中,我们学习了推导式的相关概念和使用方法,使用推导式的方法,可以减少代码的输入量、提高可读性,是Python中非常受欢迎的一种形式。
今天开始,我们将要学习的是Python中最重要、最基础的一种代码组织和代码复用形式——函数。
这里的函数既包括我们之前学习的、在Python中已经定义好的函数,或者说叫做内置函数,也包括我们自己定义的、实现我们期望功能的函数,即自定义函数。如无特殊说明,后面所说的函数一般是指自定义函数。
根据经验,如果需要多次重复相同或类似的代码,就非常值得写一个可复用的函数。通过给一组Python语句定义一个名称,形成函数,可以更好地组织我们的代码,提高可读性。
那么什么情况需要自定义函数,刚才所说的代码组织和代码复用又是什么意思呢?
让我们先通过一个小实例,看一下函数是如何实现代码组织和代码复用的。
因为这个实例只是用来展示函数的作用,因此在代码编写方面可能不是很严谨,对于一些没有考虑全面或者可能报错的地方,请大家暂且忽略。如果有兴趣的话,建议大家自己也先编写一下这个程序,也是复习我们过去所学内容和练习的机会。
1、不使用自定义函数的编程实例
假设有A、B两个小朋友掷骰子,每个小朋友投掷三次,以三次掷出的骰子点数最大的一次为准,较大的一方取得胜利。
根据我们之前学习的方法,可以写出如下程序:
In [1]: import random
A = []
for i in range(3):
result = random.randrange(1, 7)
A.append(result)
A_result = max(A)
B = []
for i in range(3):
result = random.randrange(1, 7)
B.append(result)
B_result = max(B)
if A_result > B_result:
print("胜利者是A。")
elif A_result < B_result:
print("胜利者是B。")
else:
print("双方打平。")
Out[1]: 双方打平。
因为这个程序比较简单,结构也不复杂,所以大家读起来并不会觉得晦涩。但即使如此,我们仔细观察程序,也有可以优化的地方。
最容易看到的一点就是得到A、B两个小朋友骰子结果的程序几乎是完全一样的,只不过我们使用了不同的变量名。
另外,最后的if-else结构虽然符合语法规则,但多层嵌套还是有点繁琐,如果能够使用更简洁的代码表示出来就好了。
上面所说的两点,用我们现有的知识可能不是很好处理,虽然也可以用其他的方法来实现,但并不能达到明显的优化效果。
那么,现在就让我们的函数出场吧,看看自定义函数是如何实现代码优化的。因为在这一部分中,我们只是为了说明自定义函数是如何实现代码组织和代码复用的,所以大家可以先不需要关注代码的语法形式。
2、使用自定义函数的编程实例
In [2]: import random
def play():
kid = []
for i in range(3):
result = random.randrange(1,7)
kid.append(result)
kid_result = max(kid)
return kid_result
def win(A, B):
if A > B:
winner = "胜利者是A。"
elif A < B:
winner = "胜利者是B。"
else:
winner = "双方打平。"
return winner
A = play()
B = play()
print(win(A, B))
Out[2]: 胜利者是B。
以上就是我们使用自定义函数编写的程序代码了。虽然从代码量上,大家可能并不觉得有什么简化(都是18行),但使用自定义函数的程序,主程序实际上只有最后三行(A = play(); B = play(); print(win(A, B))),其它部分(def开头,return结尾)都是我们自定义函数的部分。
在这个实例中,我们定义了两个函数——play()和win(),其作用分别是计算小朋友投掷子的结果和判断比赛输赢的结果。
因此,一方面,优化后的程序中,没有再出现重复的代码,利用自定义函数实现了代码复用;另一方面,优化后的程序中,最终的结果只使用了一条语句就实现了结果的输出,也即实现了代码的组织优化。
看到这,有朋友可能会说了,虽然只用了一句话输出结果,但在函数中同样使用了复杂的if-else结构的语句,并不比原来的代码简化了呢?
这是一个非常好的问题,同时也是自定义函数最有价值的地方。通过自定义函数的方式,可以将原来程序中重复、复杂、结构不清晰的部分优化,避免代码的重复,或者将一个个复杂的代码块定义成函数,使主程序的结构更加清晰。
所以,虽然我们新的代码并不比原代码行数少,但却利用自定义函数,避免了重复代码的出现,同时简化了主程序的代码,并使其结构更加清晰,也更易阅读和理解。
因为我们的实例非常简单,如果是非常复杂的实例或者项目,利用自定义函数的方式去编写,简化和优化的空间就非常大了,而不仅仅是我们现在看到的这点差别了。
此外,还有我们常常使用的内置函数,其实就是Python开发者编写的自定义函数,我们在调用的时候也是非常方便、非常简洁的。很难想象如果这些内置函数也需要我们在程序中自己编写完整代码的情形吧。
所以,在本篇开头我们就说过,自定义函数是Python中最基础的编程方法。接下来,我们就开始自定义函数的具体讲解了,大家也就能逐渐体会自定义函数的强大了。
3、自定义函数的语法形式
在上面的实例中,我们已经看到了,自定义函数是一个以关键字def开头、关键字return结尾的代码块。编写自定义函数的过程叫做函数声明,在主程序中使用自定义函数的过程叫做函数调用。一个典型的函数是由如下结构组成的:
def 函数名称(参数列表):
函数体
return 变量名
其中,根据自定义函数的需要,参数列表可以省略,只写一个括号即可,就像我们刚才实例中的play()函数一样。也可以包括一个或者多个参数,就像我们刚才实例中的win(A, B)函数一样。对于函数参数的具体讲解我们将在下一篇中进行介绍。
函数一般都是以return语句结尾,用来退出函数,并返回函数运行结果。在一个函数中,既可以有多个return返回语句,也可以可以省略return,此时会自动返回None,就像下面这个简单的程序一样。
In [3]: def hello():
print("这个函数的作用就是打印这句话,不需要有什么返回值。")
print("下面开始运行hello()函数:")
hello()
Out[3]: 下面开始运行hello()函数:
这个函数的作用就是打印这句话,不需要有什么返回值。
如果给hello()函数加上参数,可以对任何传入函数的内容进行自定义形式的打印。
In [4]: def hello(text):
print("这个函数的作用就是打印传入函数的这句话:", text)
a = "打印我吧!"
hello(a)
Out[4]: 这个函数的作用就是打印传入函数的这句话:
打印我吧!
在上面的例子中我们也可以看到,输入函数的变量名称和定义函数的变量名称是可以不同,具体的讲解我们也是在下一篇中进行。
最后,再给大家介绍一个标准化的Python编程结构。除了我们刚刚自定义函数时使用的def...return...进行函数的声明外,还要将主程序定义成main()函数,同时使用“if __name__ = '__main__'”这样一个语句引导整个程序的运行。所以,我们之前编写的投骰子的程序,就可以写为这种规范性的Python语句了。
import random
def play():
kid = []
for i in range(3):
result = random.randrange(1,7)
kid.append(result)
kid_result = max(kid)
return kid_result
def win(A, B):
if A > B:
winner = "胜利者是A。"
elif A < B:
winner = "胜利者是B。"
else:
winner = "双方打平。"
return winner
def main():
A = play()
B = play()
print(win(A, B))
if __name__ == '__main__':
main()
在这样的结构中,我们实际上是把主程序定义成了main()函数,因为“if __name__ == '__main__':”是永远为真的,所以main()函数也必然运行。
之所以把Python程序写成这样的结构,主要是为了防止其它程序调用该脚本时直接运行,具体的解释可能比较复杂,大家可以暂且不用理会,只需要以后在编写程序时,利用好这样的标准化Python结构就可以了。
在这一篇中,我们主要介绍了自定义函数的基本概念和语法格式,并通过几个小的实例,说明了自定义函数的作用。在下一篇中,我们将对自定义函数的声明、参数和返回值等进行详细的介绍,敬请关注。
感谢阅读本文!如有任何问题,欢迎留言,一起交流讨论^_^
要阅读《手把手陪您学Python》系列文章的其他篇目,请关注公众号点击菜单选择,或点击下方链接直达。
《手把手陪您学Python》1——为什么要学Python?
《手把手陪您学Python》2——Python的安装
《手把手陪您学Python》3——PyCharm的安装和配置
《手把手陪您学Python》4——Hello World!
《手把手陪您学Python》5——Jupyter Notebook
《手把手陪您学Python》6——字符串的标识
《手把手陪您学Python》7——字符串的索引
《手把手陪您学Python》8——字符串的切片
《手把手陪您学Python》9——字符串的运算
《手把手陪您学Python》10——字符串的函数
《手把手陪您学Python》11——字符串的格式化输出
《手把手陪您学Python》12——数字
《手把手陪您学Python》13——运算
《手把手陪您学Python》14——交互式输入
《手把手陪您学Python》15——判断语句if
《手把手陪您学Python》16——循环语句while
《手把手陪您学Python》17——循环的终止
《手把手陪您学Python》18——循环语句for
《手把手陪您学Python》19——第一阶段小结
《手把手陪您学Python》20——列表
《手把手陪您学Python》21——元组
《手把手陪您学Python》22——字典
《手把手陪您学Python》23——内置序列函数
《手把手陪您学Python》24——集合
《手把手陪您学Python》25——列表推导式
For Fans:关注“亦说Python”公众号,回复“手26”,即可免费下载本篇文章所用示例语句。