(一)把一段处理写成函数
1. 定义、调用与返回
先只处理一件事:接收每天的分钟数,返回合计。
# def 建立函数;调用时,传入的数据由形参 values 接收。
def total_minutes(values):
total = 0
for minutes in values:
total += minutes
return total
# 两次调用使用同一份处理代码,各自建立本次调用的局部名称。
this_week = total_minutes([20, 35])
last_week = total_minutes([10, 15, 30])
print(this_week, last_week)输出 55 55。def 后面依次是函数名、圆括号中的参数和冒号;缩进部分是函数体。执行到 def 时,Python 创建函数对象,并把名称 total_minutes 绑定到它;函数体要等调用时才执行。
定义中的 values 叫形参,调用时的 [20, 35] 叫实参。第一轮调用把实参对象交给 values,进入循环得到 55,再由 return 把这个对象交回调用处。于是原先的 total_minutes([20, 35]) 得到结果 55,随后才完成 this_week = 55。
两次调用各有自己的 total。第二次从 0 开始累加,不会接着第一次的 55 计算。函数名与变量名一样采用小写单词加下划线;名称尽量说清动作,例如 parse_command、count_titles。
2. 返回结果与显示结果
下面两段处理都能让屏幕出现 55,但调用者拿到的东西不同:
# print 在终端显示内容;没有写 return 的函数最终返回 None。
def show_total(values):
print(sum(values))
# return 把值交给调用者;函数内部不负责显示。
def calculate_total(values):
return sum(values)
shown = show_total([20, 35])
calculated = calculate_total([20, 35])
print(shown)
print(calculated + 5)输出依次是 55、None、60。shown 得到的是函数返回的 None,不是刚才打印的数字。需要后续排序、保存或生成网页时,返回数据更便于继续组合;负责显示的函数则可以直接打印。
执行到 return,本次调用立即结束。单独写 return,或者执行到函数体末尾,都返回 None。它只结束当前函数,不会自动结束外层程序。
3. 多个结果、提前返回与文档字符串
# 三引号字符串放在函数体开头,用来说明函数的用途。
def summarize(values):
"""返回总分钟数与平均分钟数。"""
if not values:
return 0, 0.0
total = sum(values)
return total, total / len(values)
# 逗号形成一个元组,调用处再按第二章的写法拆包。
total, average = summarize([20, 35])
print(total, average)
print(summarize([]))
print(summarize.__doc__)输出为 55 27.5、(0, 0.0),以及文档字符串中的说明。这里并没有同时返回两条独立的数据通道;return total, average 返回一个二元组,左侧再拆成两个名称。__doc__ 是函数对象保存说明文字的属性,也可以通过 help(summarize) 查看帮助。
空列表进入第一处分支,直接返回;有记录时才计算除法。把可以先完成的情况提前返回,后面的代码就能顺着主要处理过程往下写。