Python编程:从入门到实践
章节

第 8 章 函数

把重复动作装进名字里,代码才开始真正可复用

第八章用函数、参数、返回值和模块,把脚本式代码推进到结构化程序设计。

章节主张

函数的真正意义不只是复用,而是让程序拥有清晰边界、职责拆分和更低维护成本。

中文释读

几乎每个初学者都会在函数这一章第一次体会到“代码终于不像一团线了”。参数、默认值、返回值、列表参数、任意数量实参和模块导入,把‘分解任务’这件事正式引入 Python 学习。作者在这一章安排得很扎实,因为函数几乎是后面类、测试、Django 视图和项目代码结构的前提。

本章知识路线

  1. 函数与模块是在训练你写可维护程序
  2. 好的抽象会隐藏细节,但保留意图

关键论点

  • 函数让重复逻辑被封装和复用。
  • 参数设计体现接口意识。
  • 模块化会显著改善大文件的可读性。

行动清单

  • 写函数前先说清楚它只负责什么。
  • 区分打印结果和返回结果。
  • 把相关函数移到模块中,练习导入与别名。

源章节深读

第 8 章 函数 在本章中,你将学习编写函数( function )。函数是带名字的代码块, ⽤于完成具体的⼯作。要执⾏函数定义的特定任务,可调⽤( call )该 函数。当需要在程序中多次执⾏同⼀项任务时,⽆须反复编写完成该 任务的代码,只需要调⽤执⾏该任务的函数,让 Python 运⾏其中的代 码即可。你将发现,使⽤函数,程序编写、阅读、测试和修复起来都 会更容易。 你还将学习各种向函数传递信息的⽅式,学习编写主要任务是显⽰信息的 函数,以及⽤于处理数据并返回⼀个或⼀组值的函数。最后,你将学习如 何将函数存储在称为模块( module )的独⽴⽂件中,让主程序⽂件更加整 洁。 8.1 定义函数 下⾯是⼀个打印问候语的简单函数,名为 greet_user(): greeter.py def greet_user(): """ 显⽰简单的问候语 """ print("Hello!") greet_user() 这个⽰例演⽰了最简单的函数结构。第⼀⾏代码使⽤关键字 def 来告诉 Python ,你要定义⼀个函数。这是函数定义,向 Python 指出了函数名,还 可以在括号内指出函数为完成任务需要什么样的信息。

8.1 定义函数

8.1 定义函数 下⾯是⼀个打印问候语的简单函数,名为 greet_user(): greeter.py def greet_user(): """ 显⽰简单的问候语 """ print("Hello!") greet_user() 这个⽰例演⽰了最简单的函数结构。第⼀⾏代码使⽤关键字 def 来告诉 Python ,你要定义⼀个函数。这是函数定义,向 Python 指出了函数名,还 可以在括号内指出函数为完成任务需要什么样的信息。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.1 定义函数 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

8.2 传递实参

8.2 传递实参 函数定义中可能包含多个形参,因此函数调⽤中也可能包含多个实参。向 函数传递实参的⽅式很多:既可以使⽤位置实参,这要求实参的顺序与形 参的顺序相同;也可以使⽤关键字实参,其中每个实参都由变量名和值组 成;还可以使⽤列表和字典。下⾯依次介绍这些⽅式。 8.2.1 位置实参 在调⽤函数时, Python 必须将函数调⽤中的每个实参关联到函数定义中的 ⼀个形参。最简单的⽅式是基于实参的顺序进⾏关联。以这种⽅式关联的 实参称为位置实参。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.2 传递实参 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

8.3 返回值

8.3 返回值 函数并⾮总是直接显⽰输出,它还可以处理⼀些数据,并返回⼀个或⼀组 值。函数返回的值称为返回值。在函数中,可以使⽤ return 语句将值返 回到调⽤函数的那⾏代码。返回值让你能够将程序的⼤部分繁重⼯作移到 函数中完成,从⽽简化主程序。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.3 返回值 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

8.4 传递列表

8.4 传递列表 你经常会发现,向函数传递列表很有⽤,可能是名字列表、数值列表或更 复杂的对象列表(如字典)。将列表传递给函数后,函数就能直接访问其 内容。下⾯使⽤函数来提⾼处理列表的效率。 假设有⼀个⽤户列表,⽽我们要向其中的每个⽤户发出问候。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.4 传递列表 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

8.5 传递任意数量的实参

8.5 传递任意数量的实参 有时候,你预先不知道函数需要接受多少个实参,好在 Python 允许函数从 调⽤语句中收集任意数量的实参。 例如⼀个制作⽐萨的函数,它需要接受很多配料,但⽆法预先确定顾客要 点多少种配料。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.5 传递任意数量的实参 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

8.6 将函数存储在模块中

8.6 将函数存储在模块中 使⽤函数的优点之⼀是可将代码块与主程序分离。通过给函数指定描述性 名称,能让程序容易理解得多。你还可以更进⼀步,将函数存储在称为模 块的独⽴⽂件中,再将模块导⼊( import )主程序。import 语句可让你在 当前运⾏的程序⽂件中使⽤模块中的代码。 通过将函数存储在独⽴的⽂件中,可隐藏程序代码的细节,将重点放在程 序的⾼层逻辑上。这还能让你在众多不同的程序中复⽤函数。将函数存储 在独⽴⽂件中后,可与其他程序员共享这些⽂件⽽不是整个程序。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.6 将函数存储在模块中 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

8.7 函数编写指南

8.7 函数编写指南 在编写函数时,需要牢记⼏个细节。应给函数指定描述性名称,且只使⽤ ⼩写字⺟和下划线。描述性名称可帮助你和别⼈明⽩代码想要做什么。在 给模块命名时也应遵循上述约定。 每个函数都应包含简要阐述其功能的注释。该注释应紧跟在函数定义后 ⾯,并采⽤⽂档字符串的格式。这样,其他程序员只需阅读⽂档字符串中 的描述就能够使⽤它:他们完全可以相信代码会如描述的那样运⾏,并且 只要知道函数名、需要的实参以及返回值的类型,就能在⾃⼰的程序中使 ⽤它。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.7 函数编写指南 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

8.8 小结

8.8 ⼩结 在本章中,你⾸先学习了如何编写函数,以及如何传递实参,让函数能够 访问完成⼯作所需的信息。然后学习了如何使⽤位置实参和关键字实参, 以及如何接受任意数量的实参。你⻅识了显⽰输出的函数和返回值的函 数,知道了如何将函数与列表、字典、if 语句和 while 循环结合起来使 ⽤,以及如何将函数存储在称为模块的独⽴⽂件中,让程序⽂件更简单、 更易于理解。最后,你了解了函数编写指南,遵循这些指南可让程序始终 保持良好的结构,对你和其他⼈来说都易于阅读。

这节解决什么:这一节主要解决《第 8 章 函数》里一个更具体的子问题:8.8 小结 该怎样落到实际代码或项目动作上。

怎么用到自己的系统:不要只把它当书中的小节标题,最好把它改写成一个你能亲手运行、修改或调试的微练习。

提醒:常见误区是只看懂例子表面流程,却没有把这一节抽成自己能迁移的规则。

辨析题

为什么函数会让程序突然变得更容易读?

本章图版学习路径

函数与模块是在训练你写可维护程序

好的抽象会隐藏细节,但保留意图