
图1:Python函数进阶核心知识体系总览
一、可变参数 *args 与 **kwargs:让函数更灵活
当我们写函数时,经常会遇到「参数个数不确定」的场景,比如要计算任意多个数字的和、打印用户的任意自定义信息。这时候就需要用到Python的可变参数:*args 用来接收任意数量的位置参数,**kwargs 用来接收任意数量的关键字参数,这是函数进阶最实用的技巧之一。
1. *args:可变位置参数
*args 会把我们传入的所有位置参数,自动打包成一个 元组(tuple),在函数里直接用 args 就能拿到所有参数。
# 计算任意多个数字的和,不管传几个数都能算
def add(*args):
total = 0
# 遍历args(元组),把每个数加起来
for num in args:
total += num
return total
# 测试:传3个数、4个数都可以,不用修改函数
print(add(1, 2, 3)) # 输出:6
print(add(10, 20, 30, 40)) # 输出:100
2. **kwargs:可变关键字参数
**kwargs 会把我们传入的所有关键字参数,自动打包成一个 字典(dict),在函数里用 kwargs 就能拿到所有键值对。
# 打印用户信息,支持任意字段,不用提前定义参数
def print_info(**kwargs):
# 遍历字典,打印每个字段和对应的值
for k, v in kwargs.items():
print(f"{k}:{v}")
# 测试:传name、age、city,甚至更多字段都可以
print_info(name="小明", age=18, city="北京")
# 输出:
# name:小明
# age:18
# city:北京
3. 组合使用:参数顺序必须严格遵守
当多种参数同时出现在函数定义里时,顺序必须严格遵循:位置参数 → 默认参数 → *args → **kwargs,顺序错了会直接触发语法报错,这是新手最容易踩的坑!
# 正确的参数顺序:位置参数a → 默认参数b → *args → **kwargs
def func(a, b=10, *args, **kwargs):
print(f"位置参数a={a}, 默认参数b={b}")
print(f"可变位置参数args={args}")
print(f"可变关键字参数kwargs={kwargs}")
# 测试调用
func(1, 2, 3, 4, x=5, y=6)
# 输出:
# 位置参数a=1, 默认参数b=2
# 可变位置参数args=(3, 4)
# 可变关键字参数kwargs={'x': 5, 'y': 6}
4. *args/**kwargs 解包用法:快速传递参数
在调用函数时,我们可以用 * 解包元组、** 解包字典,把批量参数一次性传给函数,不用手动逐个填写,让代码更简洁。
# 定义一个加法函数
def add(a, b):
return a + b
# 1. 用*解包元组,快速传递位置参数
nums = (10, 20)
print(add(*nums)) # 等价于 add(10, 20),输出:30
# 2. 用**解包字典,快速传递关键字参数
info = {"name":"小明", "age":18}
print_info(**info) # 等价于 print_info(name="小明", age=18)

图2:*args与**kwargs核心区别对比
二、递归函数:自己调用自己的编程技巧
递归函数,简单说就是「在函数内部调用自己」。用递归可以用非常简洁的代码,解决复杂的问题,比如阶乘、斐波那契数列、汉诺塔等。但递归有两个必须满足的核心条件:基线条件(终止递归)+ 递归条件(缩小问题规模),否则会无限递归导致栈溢出。
经典案例1:阶乘计算
阶乘的定义是 n! = n × (n-1) × (n-2) × … × 1,用递归实现非常简单。
# 递归实现阶乘:n! = n × (n-1)!
def factorial(n):
# 基线条件:n=1时,直接返回1,终止递归(必须有!)
if n == 1:
return 1
# 递归条件:n × 阶乘(n-1),不断缩小问题规模
return n * factorial(n-1)
# 测试:计算5的阶乘 5! = 5×4×3×2×1 = 120
print(factorial(5)) # 输出:120
经典案例2:斐波那契数列
斐波那契数列的规律是:第1项=1,第2项=1,从第3项开始,每一项等于前两项之和。
# 递归实现斐波那契数列:第n项 = 第n-1项 + 第n-2项
def fib(n):
# 基线条件:n≤2时,直接返回1
if n <= 2:
return 1
# 递归条件:第n项 = 前两项之和
return fib(n-1) + fib(n-2)
# 测试:计算第10项斐波那契数
print(fib(10)) # 输出:55
递归使用注意事项(新手必看)
- 必须有基线条件:没有终止条件会无限递归,导致程序崩溃(栈溢出)
- Python默认最大递归深度约1000层:处理大数据量时慎用递归,优先用循环
- 递归代码简洁但效率低:可以用「记忆化」优化重复计算,提升效率

图3:递归函数核心执行流程
三、变量作用域:局部vs全局,代码可访问范围
变量的作用域,决定了代码能在哪些位置访问这个变量。搞懂作用域,能帮你避免「变量污染」「变量未定义」等常见bug。核心分为两类:局部作用域(函数内)和全局作用域(函数外)。
1. 局部变量:函数内定义,仅函数内可访问
在函数内部定义的变量,就是局部变量,只能在这个函数里访问,函数外无法访问。
def func():
# 局部变量num,仅在func函数内可访问
num = 10
print(num) # 函数内可以正常打印
func() # 调用函数,输出:10
# print(num) # 函数外访问会报错:NameError: name 'num' is not defined
2. 全局变量:函数外定义,整个程序可访问
在函数外部定义的变量,就是全局变量,整个程序(包括函数内)都可以访问(但默认只能读取,不能修改)。
# 全局变量num,整个程序都可以访问
num = 100
def func():
print(num) # 函数内可以读取全局变量,输出:100
func()
print(num) # 函数外也可以访问,输出:100
3. global 关键字:函数内修改全局变量
如果要在函数内修改全局变量,必须用 global 关键字声明,否则Python会把它当成局部变量,不会修改全局变量。
num = 100 # 全局变量
def func():
global num # 声明:这里的num是全局变量,不是局部变量
num = 200 # 修改全局变量的值
func()
print(num) # 全局变量被修改,输出:200
4. nonlocal 关键字:嵌套函数修改外层局部变量
如果是嵌套函数(函数里套函数),内层函数要修改外层函数的局部变量,需要用 nonlocal 关键字声明。
def outer():
num = 10 # 外层函数的局部变量
def inner():
nonlocal num # 声明:这里的num是外层函数的局部变量
num = 20
print(f"内层函数修改后:{num}")
inner()
print(f"外层函数访问:{num}") # 外层函数能看到修改后的值
outer()
# 输出:
# 内层函数修改后:20
# 外层函数访问:20
四、匿名函数 lambda:一次性的简洁函数
lambda 表达式,用来创建一次性、简单的匿名函数,语法极度简洁,不用给函数命名,适合写单行的简单逻辑,常配合高阶函数(如 map、filter、sorted)使用。
1. lambda 基础语法
lambda 的语法非常简单:lambda 参数: 表达式,表达式的结果就是函数的返回值,只能有一个表达式,不能写多行。
# 用lambda创建一个加法函数 add = lambda a, b: a + b print(add(10, 20)) # 调用函数,输出:30 # 等价于普通函数: # def add(a, b): # return a + b
2. 经典案例:配合 sorted 自定义排序
lambda 最常用的场景,就是给 sorted 函数做排序键,实现自定义排序规则。
# 学生列表,每个元素是字典,包含姓名和年龄
students = [
{"name": "小明", "age": 18},
{"name": "小红", "age": 16},
{"name": "小刚", "age": 20}
]
# 用lambda作为排序键,按年龄升序排序
sorted_students = sorted(students, key=lambda x: x["age"])
print(sorted_students)
# 输出:按年龄从小到大排序的学生列表
3. 配合 map、filter 使用:批量处理数据
map 用来对列表的每个元素执行操作,filter 用来过滤列表元素,配合 lambda 可以用一行代码完成批量处理。
# 1. map:对列表每个元素执行操作(比如给每个数乘2) nums = [1, 2, 3, 4] double = list(map(lambda x: x*2, nums)) print(double) # 输出:[2, 4, 6, 8] # 2. filter:过滤列表元素(比如只保留偶数) even = list(filter(lambda x: x%2 == 0, nums)) print(even) # 输出:[2, 4]
五、高阶函数:函数式编程的核心
高阶函数的定义很简单:接收函数作为参数,或者返回函数作为结果的函数。它是函数式编程的核心,能让代码更灵活、更抽象,适合封装通用逻辑。
经典案例:函数作为参数,实现通用计算
# 通用计算函数,接收两个数和一个操作函数作为参数
def calculate(a, b, operation):
# 调用传入的操作函数,返回结果
return operation(a, b)
# 定义不同的操作函数(也可以用lambda)
add = lambda x, y: x + y
sub = lambda x, y: x - y
# 用同一个calculate函数,实现不同的计算
print(calculate(10, 5, add)) # 加法,输出:15
print(calculate(10, 5, sub)) # 减法,输出:5
六、综合实战案例:把进阶知识用起来
案例1:用递归实现汉诺塔(经典算法)
汉诺塔是递归的经典应用,用递归可以用几行代码解决这个复杂问题。
# 汉诺塔递归实现
# n:盘子数量,a:起始柱,b:中间柱,c:目标柱
def hanoi(n, a, b, c):
# 基线条件:只有1个盘子,直接从a移到c
if n == 1:
print(f"{a} → {c}")
return
# 递归条件:把n-1个盘子从a移到b(用c做中间柱)
hanoi(n-1, a, c, b)
# 把最下面的1个盘子从a移到c
print(f"{a} → {c}")
# 把n-1个盘子从b移到c(用a做中间柱)
hanoi(n-1, b, a, c)
# 测试:3层汉诺塔
hanoi(3, "A", "B", "C")
案例2:用 lambda + sorted 实现多条件排序
用 lambda 可以实现多条件排序,比如先按年龄升序,再按姓名升序。
# 学生列表,包含姓名和年龄
students = [
{"name": "Bob", "age": 18},
{"name": "Alice", "age": 18},
{"name": "Charlie", "age": 20}
]
# 多条件排序:先按年龄升序,再按姓名升序
sorted_students = sorted(students, key=lambda x: (x["age"], x["name"]))
for s in sorted_students:
print(s)
# 输出:
# {'name': 'Alice', 'age': 18}
# {'name': 'Bob', 'age': 18}
# {'name': 'Charlie', 'age': 20}
七、高频易错点避坑指南:新手一次性避开
可变参数顺序错误
参数顺序必须严格遵循:位置参数 → 默认参数 → *args → **kwargs,顺序错会直接报语法错
递归无基线条件,导致栈溢出
递归必须有明确的终止条件(基线条件),否则会无限递归,导致程序崩溃
函数内修改全局变量未加 global
不加 global 会创建局部变量,不会修改全局变量,这是新手最容易踩的坑之一
lambda 只能有一个表达式
lambda 是单行匿名函数,不能写多行复杂逻辑,语法有严格限制
延伸学习推荐
想深入学习官方文档,可查看Python官方函数进阶文档;
学完本篇内容,建议回顾Python函数入门全攻略,夯实基础,做到融会贯通。
八、核心知识点总结:快速复习
- *args:接收任意位置参数,自动打包为元组
- **kwargs:接收任意关键字参数,自动打包为字典
- 递归函数:函数内调用自身,必须有基线条件终止递归
- 作用域:局部变量仅函数内可访问,global/nonlocal 用于修改变量
- lambda 表达式:匿名单行函数,常配合 sorted、map、filter 使用
- 高阶函数:可接收/返回函数,实现灵活的函数式编程
本文是Python零基础入门系列的进阶篇,承接函数入门内容。更多新手能直接上手的Python教程,可查看往期内容:
Python输入输出与格式化技巧、
Python变量与变量名全解析。
版权声明:本文所有内容(含代码、图片、文字)均为原创,未经授权禁止任何形式的转载、抄袭、洗稿
如需转载,请联系作者获得授权,并在正文开头显著位置标注原文链接和作者信息!
下一篇预告:Python 面向对象编程,从类到对象,彻底掌握 OOP!
Python函数进阶
Python零基础
Python进阶
Python函数
lambda
递归

渝公网安备50022402001073号
Pingback: 零基础学 Python 核心编程:7 大核心主题 + 实战进阶全攻略 - 小白 编程 笔记
Pingback: Python核心编程:7大核心主题+实战进阶全攻略,小白一站式学Python - 小白 编程 笔记