⚡ Python 函数:代码复用的魔法

Evan Zhou

Tech Chronicles|Jan 26, 2025|Last edited: Dec 31, 2025|
type
status
date
slug
summary
tags
category
icon
password
comment
在 Python 编程中,函数不仅仅是简化代码的工具,更是代码复用模块化编程的核心。它们让我们的代码更加整洁、易读、可维护,甚至可以轻松地复用,避免写“重复的轮子”。你是否曾经在代码中多次复制粘贴相同的逻辑?你是否希望代码更加优雅,而不是一团混乱?如果你的答案是 YES,那么 Python 函数 将是你最好的朋友!🚀

为什么要用函数?

在编写程序时,我们经常会遇到重复性任务,例如:
  • 计算公式(如求平方、计算平均值)
  • 数据处理(如清理数据、读取文件)
  • 业务逻辑(如用户认证、消息处理)
如果每次都手动写相同的代码,不仅会增加出错的风险,还会让代码臃肿且难以维护。而函数的出现,正是为了解决这个问题!✨
函数的优势:
  1. 减少重复代码——写一次,调用多次,省时省力!
  1. 提高代码可读性——代码变得更加清晰,逻辑更直观!
  1. 便于维护——当需要修改时,只需调整函数内部逻辑,而不必修改多处代码!
  1. 更好的代码结构——让程序更加模块化,易于扩展!
一句话总结:函数让代码更加优雅、简洁、高效!

📌 1. 什么是函数?

函数(Function) 是一种将特定操作封装起来的代码块,可以通过函数名进行调用。函数的核心优势是 代码复用:通过定义一次函数,可以多次调用,避免代码重复,减少维护难度。

🔹 函数的组成

一个简单的 Python 函数由以下几个部分组成:
  • 函数定义:通过 def 关键字来定义函数。
  • 参数:函数可以接收输入(即参数)。
  • 返回值:函数可以返回计算结果或操作的结果。

📌 2. 如何定义和调用函数

🔹 定义函数

Python 中通过 def 关键字来定义一个函数,后面跟上函数名、圆括号(可以包含参数),然后是冒号 :。函数体在缩进块中。
示例:

🔹 调用函数

定义函数后,我们可以通过 函数名 来调用它,并传入相应的参数。
示例:

📌 3. 函数参数与返回值

在 Python 中,函数的灵活性很大程度上体现在 参数传递返回值 上。合理地使用参数类型,不仅可以增强代码的可读性,还可以让函数更具通用性。让我们深入探讨函数参数的不同类型及其最佳实践。💡

🔹 参数的种类

Python 函数支持多种参数传递方式,每种方式都有其独特的适用场景:

🔸 位置参数(Positional Arguments)

  • 位置参数是最常见的参数类型,按照定义的顺序传递值。
  • 传参时顺序很重要,否则会导致错误或意外的结果。
📌 示例:
❌ 错误示例(参数顺序错误):

🔸 关键字参数(Keyword Arguments)

  • 关键字参数允许使用参数名指定值,避免因顺序错误导致的错误
  • 这种方式提升了代码的可读性,特别是当函数参数较多时。
📌 示例:

🔸 默认参数(Default Arguments)

  • 默认参数用于给定默认值,使得调用函数时可以省略该参数,而 Python 会自动填充默认值。
  • 默认参数必须放在所有非默认参数的后面,否则会报错。
📌 示例:
错误示例(默认参数放在前面):

*🔸 可变参数(*args 和 kwargs)

当我们不确定传入参数的个数时,可以使用可变参数:
  • args:接受多个位置参数,以 元组(Tuple) 的形式传递。
  • *kwargs:接受多个关键字参数,以 字典(Dict) 的形式传递。
📌 *示例(args):
  • args 会将所有参数打包成一个元组 (1, 2, 3) 并传递到函数内部。
📌 **示例(kwargs):
  • *kwargs 允许我们传递任意数量的键值对,并且可以在函数内部处理它们。
📌 示例(混合使用):
最佳实践:
  1. 先写 位置参数
  1. 然后是 默认参数
  1. 接着是 args
  1. 最后是 *kwargs
示例:

🔹 返回值(Return Statement)

Python 的 return 语句允许函数返回数据,返回值可以是 单个值、多个值、列表、字典等。

🔸 返回单个值


🔸 返回多个值

Python 允许返回多个值,默认情况下以 元组(Tuple) 形式返回:
  • 多个返回值会自动打包成元组 (8, 15),然后可以通过解包赋值。

🔸 提前终止函数

如果 return 语句被执行,函数将立即终止

🔸 返回字典

如果返回的值较多,可以使用字典增强可读性

🔸 返回 None

如果 return 语句没有提供值,或者根本没有 return,Python 默认返回 None

📌 总结

参数类型
描述
示例
位置参数
按顺序传递参数
func(1, 2, 3)
关键字参数
通过参数名传递
func(a=1, b=2)
默认参数
设定默认值
func(a=1, b=2)
*args
接受多个位置参数
func(1, 2, 3, 4)
**kwargs
接受多个关键字参数
func(a=1, b=2, c=3)

Python 的函数参数机制提供了极大的灵活性,合理使用不同类型的参数,可以让代码更加易读、优雅、高效。🚀

📌 4. Lambda 表达式:简化函数

🔹 什么是 Lambda 表达式?

在 Python 中,Lambda 表达式(也称为 匿名函数)是一种简洁的函数定义方式,专门用于定义短小、一次性使用的函数。它的语法结构如下:
特点:
  • 没有 def 关键字,一行代码搞定函数定义!
  • 只能包含一个表达式,但可以有多个参数。
  • 隐式 return,不需要写 return 关键字,结果会自动返回。

🔹 Lambda 表达式 vs. 普通函数

如果我们用 def 定义一个求和函数:
使用 Lambda 表达式,我们可以更简洁地定义它:
🚀 Lambda 适合简短的操作,但不适合复杂逻辑。如果函数体超过一行代码,请使用 def 定义普通函数!

🔹 Lambda 的常见用法

Lambda 表达式通常用于高阶函数(如 map()filter()sorted()),让代码更加简洁直观。

📌 1. 用于 map() —— 批量计算

map() 可以对可迭代对象的每个元素应用函数,并返回新的值:
等价的普通函数写法:
对比结果:Lambda 更简洁直观!🚀

📌 2. 用于 filter() —— 筛选数据

filter() 只保留满足条件的元素:
作用:过滤出所有偶数,避免 for 循环 + if 判断的冗长代码。

📌 3. 用于 sort() —— 按自定义规则排序

sort() 可用于对列表排序,默认按升序排列:
💡 说明:
  • x[1] 代表按照元组的第二个值排序。
  • 等价写法(普通函数):Lambda 让代码更直观!

    📌 4. 用于 reduce() —— 累积计算

    reduce() 需要 functools 模块,它可以连续累积计算
    作用:累乘所有元素,等价于:
    🔥 当需要连续计算时,reduce() 是一个简洁的选择!

    🔹 Lambda 表达式的适用场景

    适合:
    • 小型、简单的函数(如 map()filter()sorted()
    • 一次性使用的函数(不需要多次定义)
    • 避免定义额外的函数,提高代码可读性
    不适合:
    • 复杂逻辑(超过一行代码)
    • 需要调试和注释的代码(普通函数更容易阅读和维护)

    📌 总结

    用法
    示例
    作用
    Lambda 基本用法
    lambda x, y: x + y
    定义匿名函数
    用于 map()
    map(lambda x: x**2, lst)
    对列表中的元素进行转换
    用于 filter()
    filter(lambda x: x % 2 == 0, lst)
    过滤列表中的元素
    用于 sort()
    sort(lst, key=lambda x: x[1])
    按特定规则排序
    用于 reduce()
    reduce(lambda x, y: x * y, lst)
    计算累计乘积

    📌 5. 局部变量与全局变量:作用域的秘密武器 🛡️

    🔹 什么是作用域?

    在 Python 中,变量的作用范围(作用域)决定了它们可以在哪些地方被访问或修改。一般来说,变量的作用域有两个主要类别:
    1. 局部变量(Local Variable):在函数内部定义的变量,仅在该函数内部可见。
    1. 全局变量(Global Variable):在函数外部定义的变量,可以在整个程序中被访问(但在函数内部直接修改需要额外处理)。

    🔹 局部变量 vs. 全局变量

    让我们来看一个例子来直观理解局部变量与全局变量的区别:
    📌 解析:
    • x = 10全局变量,它可以在 example() 之外的任何地方访问。
    • example() 内部重新定义了 x = 20,它不会影响全局变量,因为它是局部变量
    • 局部变量的作用域仅限于 example() 内部,因此 example() 外部的 x 依然是全局变量 10

    🔹 在函数内部修改全局变量

    默认情况下,函数内部不能直接修改全局变量,否则 Python 认为你是在定义一个新的局部变量。例如:
    ❌ 运行时报错:UnboundLocalError: local variable 'x' referenced before assignment
    为什么会这样?
    • 因为 x = x + 5 试图在局部作用域中修改 x但 Python 认为 x 是局部变量,而在它被赋值之前,它其实还不存在。

    ✅ 解决方案 1:使用 global 关键字

    如果确实需要在函数内部修改全局变量,可以使用 global 关键字:
    📌 注意:
    • 使用 global x 之后,x 不再是局部变量,而是全局变量
    • 这意味着函数 modify_global() 可以直接修改全局变量 x 的值
    但一般不建议在函数内部直接修改全局变量,因为这可能会导致代码难以维护。尽可能使用参数传递和返回值的方式,而非 global

    🔹 在嵌套函数中修改外部变量(nonlocal 关键字)

    在 Python 中,我们可以定义嵌套函数(函数内部定义另一个函数)。如果希望在嵌套函数内部修改外部函数的变量,但不希望影响全局变量,可以使用 nonlocal 关键字。

    📌 示例:nonlocal 关键字

    📌 运行结果:
    💡 解析:
    • nonlocal x 告诉 Python,这里的 x 不是 inner() 内部的局部变量,而是 outer() 作用域的变量
    • inner() 修改了 x,那么 outer() 内的 x 也会改变,但全局变量不会受影响
    • 如果不使用 nonlocal,那么 x 会被视为 inner() 的局部变量,并导致 UnboundLocalError

    🔹 总结

    变量类型
    定义位置
    作用范围
    修改方式
    局部变量
    函数内部
    仅在函数内部可见
    直接赋值
    全局变量
    函数外部
    程序的任何地方
    需使用 global 关键字
    nonlocal 变量
    外部函数(嵌套函数)
    作用于外部函数但不是全局
    需使用 nonlocal 关键字

    📌 6. 小结

    在本篇博客中,我们全面探讨了 Python 函数的核心概念,从 基本定义参数传递,再到 返回值的灵活应用,甚至延伸到 Lambda 表达式变量作用域管理。通过这些内容,你已经掌握了让代码更简洁、高效、可复用的强大工具。🚀

    🔹 你现在应该掌握的关键点

    函数的定义与调用——用 def 关键字创建函数,简化代码结构。
    参数的多种形式——位置参数、关键字参数、默认参数、可变参数(*args / **kwargs),让函数更加灵活。
    返回值的多样性——返回单个值、多个值(元组)、字典等数据结构,提高函数的可扩展性。
    Lambda 表达式——用更简洁的方式定义小型匿名函数,提升代码的可读性和可维护性。
    局部变量 vs. 全局变量——理解作用域规则,学会用 globalnonlocal 关键字控制变量的访问范围。

    🔹 继续探索!

    🎯 你可以尝试用 Python 编写自己的函数库,将常用逻辑封装起来,提高代码复用率!
    🎯 练习使用 Lambda 表达式,看看如何在 map()filter()sorted() 等高阶函数中简化代码。
    🎯 深入理解 作用域规则,避免全局变量的滥用,让你的代码更可维护。

    📚 练习题:Python 函数实战

    在本章的学习过程中,我们探索了 Python 函数的定义、参数传递、Lambda 表达式,以及变量作用域的概念。现在,是时候挑战自己,动手实践这些知识点了!💡💪

    1️⃣ 定义一个计算平方的函数

    题目描述:
    编写一个函数 square(),接收一个数 n,返回 n 的平方,并调用该函数进行测试。
    📌 示例:
    输入示例: 4
    输出示例: 4 的平方是 16

    2️⃣ 计算多个数的平均值

    题目描述:
    编写一个函数 average(),可以接收多个数(可变参数 *args),返回这些数的平均值。
    📌 示例:
    输入示例: 2, 4, 6, 8
    输出示例: 5.0

    3️⃣ 计算阶乘(Factorial)

    题目描述:
    编写一个函数 factorial(n),计算 n 的阶乘(n! = 1 × 2 × ... × n),并使用递归实现。
    📌 示例:
    输入示例: 5
    输出示例: 5 的阶乘是 120

    4️⃣ 交换两个变量的值

    题目描述:
    编写一个函数 swap(a, b),交换两个变量的值,并返回交换后的结果。
    📌 示例:
    输入示例: x=5, y=10
    输出示例: x = 10, y = 5

    5️⃣ 判断一个数是否为质数

    题目描述:
    编写一个函数 is_prime(n),判断 n 是否为 质数(Prime Number),如果是返回 True,否则返回 False
    📌 示例:
    输入示例: 7
    输出示例: 7 是质数

    6️⃣ 使用 Lambda 表达式计算两个数的和

    题目描述:
    使用 Lambda 表达式 定义一个匿名函数,计算两个数的和。
    📌 示例:
    输入示例: 3, 5
    输出示例: 8

    7️⃣ 使用 Lambda 实现列表排序

    题目描述:
    给定一个由元组 (name, age) 组成的列表,请使用 Lambda 表达式按照年龄升序排列。
    📌 示例:
    输出示例: [('Bob', 20), ('Alice', 25), ('Charlie', 30)]

    8️⃣ 计算列表中所有偶数的平方

    题目描述:
    使用 map()filter() 结合 Lambda 表达式,计算列表中所有偶数的平方。
    📌 示例:
    输出示例: [4, 16, 36, 64]

    9️⃣ 作用域测试(global & local)

    题目描述:
    编写代码测试 局部变量全局变量 之间的作用域关系。
    📌 示例:
    输出示例:

    🔟 修改全局变量

    题目描述:
    编写程序,在函数内部修改全局变量,并观察运行结果。
    📌 示例:
    输出示例: 20

    💡 通过这些练习,你可以更熟练地使用函数,提高代码的复用性可读性。试着自己动手编写代码,巩固这些概念吧!🚀💪

    ⏭️ 下一节预告:📦 Python 模块与包:高效组织代码的秘诀

    在 Python 编程中,随着代码量的增加,如何组织代码变得至关重要。在下一篇文章中,我们将深入探讨 Python 模块与包,帮助你学会:
    • 模块化编程:如何拆分代码,使其更清晰、可复用。
    • 模块的导入与使用importfrom ... import ...sys.path 等。
    • Python 标准库:探索 Python 自带的强大工具箱。
    • 创建自己的 Python 包:如何封装代码并在多个项目中复用。
    模块化让代码更清晰,包让代码更有层次感。下一节,让我们一起掌握高效组织代码的艺术!📂✨
    📌 敬请期待! 🚀
     
    Loading...