函数
到目前为止,我们的 Python 代码已经实现了很多小功能。但是想复用这些代码,就需要用函数将其封装为可管理的代码段。 代码复用的第一步是使用函数。
函数的功能
函数是模块化程序设计的基本构成单位,使用函数具有如下优点。
- 实现模块化程序设计:通过把程序分割为不同的功能模块可以实现自顶向下的结构化设计。
- 减少程序的复杂度:简化程序的结构,提高程序的可阅读性。
- 实现代码的复用:一次定义多次调用,实现代码的可重用性。
- 提高代码的质量:实现分割后子任务的代码相对简单,易于开发、调试、修改和维护。
Python 中函数的分类
在 Python 语言中函数可以分为以下 4 类。
- 内置函数:Python 语言内置了若干常用的函数,例如
abs()
、len()
等,在程序中可以直接使用。 - 标准库函数:Python 语言安装程序同时会安装若干标准库,例如
math
、random
等。通过import
语句可以导入标准库,然后使用其中定义的函数。 - 第三方库函数:Python 社区提供了许多其他高质量的库,例如 Python 图像库等。在下载、安装这些库后,通过
import
语句可以导入库,然后使用其中定义的函数。 - 自定义函数:本章将详细讨论函数的定义和调用方法。
简单函数
函数:就是 封装了一段可被重复调用执行的代码块。通过此代码块可以 实现大量代码的重复使用。
函数的使用包含两个步骤:
- 定义函数 —— 封装独立的功能
- 调用函数 —— 享受封装的成果
函数的作用,在开发程序时,使用函数可以提高编写的效率以及代码的重用
函数的声明
def
:表示函数的关键字,是英文define
的缩写- 函数名:函数的名称,后续根据函数名调用函数,函数名称应该能够表达函数封装代码的功能
arg
: 即argument
参数- 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出
[11,22,38,888,2]
中的最大数等... - 函数名称的命名应该符合标识符的命名规则
- 可以由 字母、下划线和数字组成
- 不能以数字开头
- 不能与关键字重名
# 声明函数
def func():
... # 函数体代码
print()
def 是声明函数的关键字,必须小写,由于函数一般是为了实现某个功能才定义的, 所以通常我们将函数名命名为动词,比如 get_sum
函数创建示例1: 定义返回两个数的平均值的函数。
参考答案
def my_average(a, b):
return (a + b) / 2
函数创建示例2: 定义计算并返回第
参考答案
def harmonic(n): # 计算并返回第 n 阶调和数(1+1/2+1/3+…+1/n)的函数
total = 0
for i in range(1, n + 1):
total += 1.0 / i
return total
调用函数
# 调用函数
函数名([实参列表]); # 通过调用函数名来执行函数体代码
# 调用的时候千万不要忘记添加小括号
说明:
函数名是当前作用域中可用的函数对象,即调用函数之前程序必须先执行
def
语句创建函数对象。函数的定义位置必须位于调用该函数的全局代码之前,故典型的 Python 程序结构顺序通常为
import 语句
>函数定义
>全局代码
。实参列表必须与函数定义的形参列表一一对应
函数调用是表达式。如果函数有返回值,可以在表达式中直接使用;如果函数没有返回值,则可以单独作为表达式语句使用。
注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。
例子: 封装计算 1-100 累加和
"""
计算1-100之间值的函数
"""
# 声明函数
def get_sum():
total = 0
for i in range(100):
total += i
print(total)
# 调用函数
get_sum()
例子: 利用函数 求两个数的最大值
参考答案
# 利用函数 求两个数的最大值
def get_max(num1, num2):
if num1 > num2:
print(num1)
else:
print(num2)
get_max(1, 3)
get_max(11, 3)
调用函数很简单的,通过 函数名()
即可完成对函数的调用
细节问题
能否将函数调用放在函数定义的上方?
- 不能!
- 因为在使用函数名调用函数之前,必须要保证
Python
已经知道函数的存在 - 否则控制台会提示
NameError: name 'f' is not defined
(名称错误:f这个名字没有被定义)
函数的功能
每一个函数都是一小段封装好的代码,里面代码的逻辑就是函数的功能。例如我们封装一个中学时代学习的线性方程。
假设有两个变量 x
和 y
,当 x
取其变化范围中的每一个特定值时,相应地有唯一的 y
与它对应,则称 y
是 x
的函数。记为 y=f(x)
,其中 x
为自变量, y
为因变量。
- 将
y = kx + b
封装成一个函数,其中k=5
,b=6
, 假设x=5
- 在函数下方调用线性方程函数,打印结果
"""
# 函数在数学组的表达形式
y = f(x)
y = kx + b
"""
参考代码
k = 5
b = 6
# define 定义
# f 为函数名
def f(x):
# 里面的内容是函数体,函数执行的代码
y = k * x + b
# return 函数的返回值
return y
参数可变
我们定义和调用一个没有参数的函数。假设需要求当 x
分别为 5
与 6
时,f(x)
的结果相加:
def f(x):
y = 5 * x + 6
return y
print('f(5):', f(5))
多次调用产生不同的结果
带参数的函数有一个非常大的好处,通过修改调用函数传入的参数,从而得到不同的值。
def f(x):
y = 5 * x + 6
return y
print('f(5):', f(5))
print('f(6):', f(6))
print('f(7):', f(7))
函数的返回值
函数是一个功能块,该功执行成功与否,需要通过返回值来告知调用者。
程序遇到的第一个 return 就会返回(退出 def 块),不会再运行第二个 return 。
def f(x):
y = 5 * x + 6
return y
return y # 永远无法生效
print(f(5))
return 之后函数就结束了,不会再执行函数内的后续代码
return 语句
在函数体中使用 return 语句可以实现从函数中返回一个值并跳出函数的功能。
案例: 编写一个函数,求
- 定义一个函数
- 函数接收一个参数 n
- 对 1 到 n 的数求和
- 打印和
参考答案
def sum_test(n):
sum = 0
for x in range(1, n + 1):
sum += x
return sum
print(sum_test(10))
多条 return 语句
return 语句可以放置在函数中的任何位置,当执行到第一个 return 语句时程序返回到调用程序。
案例-判断素数示例: 获取 0 - 100 之间的素数
- 先编写判断一个数是否为素数的函数
- 循环判断并输出 1~99 中的素数
提示
素数又叫做质素,指的是大于1且不能被1和自身以外的任何其他数整除的数字。
参考答案
def is_prime(n):
if n <= 1:
return False
for i in range(2, n):
# print(i, end='\t')
if n % i == 0:
return False
return True
for i in range(100):
if is_prime(i):
print(i, end=' ')
返回多个值
在函数体中使用 return 语句可实现从函数返回一个值并跳出函数。如果需要返回多个值,则可以返回一个元组。
案例:编写函数,返回一个随机列表。先编写一个函数,生成由 n 个随机整数构成的列表,然后编写测试代码,生成并输出由 5 个随机整数构成的列表的各元素值。
import random
def random_array(n):
a = []
for i in range(n):
a.append(random.randint(0, 9))
return a
b = random_array(5)
print(b)
函数的其他形式
函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形式
- 无参数,无返回值
- 无参数,有返回值
- 有参数,无返回值
- 有参数,有返回值
案例:函数复用
"""
复利公式:s = p(1 + i)^n
余额宝 兴全添利宝 年化 2.5610%
假设本金(principal)10000
1、请问分别存 5年 10年 15年 20年后 本金利息共多少
2、如果利率(interest)变成 6% 分别存 5年 10年 15年 20年后 本金利息共多少
3、如果本金变成 20000,利率不变 分别存 5年 10年 15年 20年后 本金利息共多少
"""
参考答案
# principal = 10000
# interest = 2.5610 / 100 #
# def 定义函数 function 函数名 principal 参数(本金) interest 参数(利率) n 参数(年)
def function(principal, interest, n):
s = principal * (1 + interest) ** n # 复利公式
return s
print('10000 2.5610% 1年 :', function(10000, 2.5610 / 100, 1))
print('10000 2.5610% 5年 :', function(10000, 2.5610 / 100, 5))
print('10000 2.5610% 10年:', function(10000, 2.5610 / 100, 10))
print('10000 2.5610% 20年:', function(10000, 2.5610 / 100, 20))
print('10000 6% 1年 :', function(10000, 6 / 100, 1))
print('10000 6% 5年 :', function(10000, 6 / 100, 5))
print('10000 6% 10年:', function(10000, 6 / 100, 10))
print('10000 6% 20年:', function(10000, 6 / 100, 20))
print('20000 6% 1年 :', function(20000, 6 / 100, 1))
print('20000 6% 5年 :', function(20000, 6 / 100, 5))
print('20000 6% 10年:', function(20000, 6 / 100, 10))
print('20000 6% 20年:', function(20000, 6 / 100, 20))
print('20000 10% 20年:', function(20000, 10 / 100, 20))
print('20000 15% 20年:', function(20000, 15 / 100, 20))
print('20000 20% 20年:', function(20000, 20 / 100, 20))
# alt + shift + 光标向下/向上拖动 (竖行模式)