Skip to content

函数

到目前为止,我们的 Python 代码已经实现了很多小功能。但是想复用这些代码,就需要用函数将其封装为可管理的代码段。 代码复用的第一步是使用函数。

函数的功能

函数是模块化程序设计的基本构成单位,使用函数具有如下优点。

  1. 实现模块化程序设计:通过把程序分割为不同的功能模块可以实现自顶向下的结构化设计。
  2. 减少程序的复杂度:简化程序的结构,提高程序的可阅读性。
  3. 实现代码的复用:一次定义多次调用,实现代码的可重用性。
  4. 提高代码的质量:实现分割后子任务的代码相对简单,易于开发、调试、修改和维护。

Python 中函数的分类

在 Python 语言中函数可以分为以下 4 类。

  1. 内置函数:Python 语言内置了若干常用的函数,例如 abs()len() 等,在程序中可以直接使用。
  2. 标准库函数:Python 语言安装程序同时会安装若干标准库,例如 mathrandom 等。通过 import 语句可以导入标准库,然后使用其中定义的函数。
  3. 第三方库函数:Python 社区提供了许多其他高质量的库,例如 Python 图像库等。在下载、安装这些库后,通过 import 语句可以导入库,然后使用其中定义的函数。
  4. 自定义函数:本章将详细讨论函数的定义和调用方法

简单函数

函数:就是 封装了一段可被重复调用执行的代码块。通过此代码块可以 实现大量代码的重复使用

函数的使用包含两个步骤:

  1. 定义函数 —— 封装独立的功能
  2. 调用函数 —— 享受封装的成果

函数的作用,在开发程序时,使用函数可以提高编写的效率以及代码的重用

函数的声明

1586348262103

  1. def :表示函数的关键字,是英文 define 的缩写
  2. 函数名:函数的名称,后续根据函数名调用函数,函数名称应该能够表达函数封装代码的功能
  3. arg : 即 argument 参数
  4. 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
  5. 函数名称的命名应该符合标识符的命名规则
    • 可以由 字母、下划线和数字组成
    • 不能以数字开头
    • 不能与关键字重名
python
# 声明函数
def func():
    ...  # 函数体代码
    print()

def 是声明函数的关键字,必须小写,由于函数一般是为了实现某个功能才定义的, 所以通常我们将函数名命名为动词,比如 get_sum

函数创建示例1: 定义返回两个数的平均值的函数。

参考答案
python
def my_average(a, b):
    return (a + b) / 2

函数创建示例2: 定义计算并返回第 n 阶调和数 1+12+13++1n 的函数。

参考答案
python
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

调用函数

python
# 调用函数
函数名([实参列表]);  # 通过调用函数名来执行函数体代码

# 调用的时候千万不要忘记添加小括号

说明:

  1. 函数名是当前作用域中可用的函数对象,即调用函数之前程序必须先执行 def 语句创建函数对象。

    函数的定义位置必须位于调用该函数的全局代码之前,故典型的 Python 程序结构顺序通常为 import 语句函数定义全局代码

  2. 实参列表必须与函数定义的形参列表一一对应

  3. 函数调用是表达式。如果函数有返回值,可以在表达式中直接使用;如果函数没有返回值,则可以单独作为表达式语句使用。

注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。

例子: 封装计算 1-100 累加和

python
""" 
   计算1-100之间值的函数
"""


# 声明函数
def get_sum():
    total = 0
    for i in range(100):
        total += i
    print(total)


# 调用函数
get_sum()

例子: 利用函数 求两个数的最大值

参考答案
python
# 利用函数 求两个数的最大值
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这个名字没有被定义)

函数的功能

每一个函数都是一小段封装好的代码,里面代码的逻辑就是函数的功能。例如我们封装一个中学时代学习的线性方程。

假设有两个变量 xy ,当 x 取其变化范围中的每一个特定值时,相应地有唯一的 y 与它对应,则称 yx 的函数。记为 y=f(x),其中 x 为自变量, y 为因变量。

  1. y = kx + b 封装成一个函数,其中 k=5 , b=6 , 假设 x=5
  2. 在函数下方调用线性方程函数,打印结果
python
"""
# 函数在数学组的表达形式
y = f(x)
y = kx + b
"""
参考代码
python
k = 5
b = 6


# define 定义
# f 为函数名
def f(x):
    # 里面的内容是函数体,函数执行的代码
    y = k * x + b
    # return 函数的返回值
    return y

参数可变

我们定义和调用一个没有参数的函数。假设需要求当 x 分别为 56 时,f(x) 的结果相加:

python
def f(x):
    y = 5 * x + 6
    return y


print('f(5):', f(5))

多次调用产生不同的结果

带参数的函数有一个非常大的好处,通过修改调用函数传入的参数,从而得到不同的值。

python
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 。

python
def f(x):
    y = 5 * x + 6
    return y
    return y  # 永远无法生效


print(f(5))

return 之后函数就结束了,不会再执行函数内的后续代码

return 语句

在函数体中使用 return 语句可以实现从函数中返回一个值并跳出函数的功能。

案例: 编写一个函数,求 1+2+3+...+n

  1. 定义一个函数
  2. 函数接收一个参数 n
  3. 对 1 到 n 的数求和
  4. 打印和
参考答案
python
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和自身以外的任何其他数整除的数字。

参考答案
python
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 个随机整数构成的列表的各元素值。

python
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 种 组合形式

  1. 无参数,无返回值
  2. 无参数,有返回值
  3. 有参数,无返回值
  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年后 本金利息共多少
"""
参考答案
python
# 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 + 光标向下/向上拖动   (竖行模式)