当前位置:首页>python>Python入门必看:Python函数基础精讲(中篇)

Python入门必看:Python函数基础精讲(中篇)

  • 2026-09-02 19:31:46
Python入门必看:Python函数基础精讲(中篇)

上篇我们讲解了函数的函数概述、基础使用、参数类型、匿名函数,本篇聚焦变量作用域、递归函数两大进阶主题,,帮你进一步掌握函数式编程的精髓。


1. 变量作用域

1.1 什么是作用域?

作用域(Scope)是指变量的有效作用范围,即在哪些代码中可以访问这个变量。

Python 中有 4 层作用域(按从内到外的顺序):

层级说明关键字
L(Local)函数内部定义的变量,局部变量—
E(Enclosing)嵌套函数的外层函数变量nonlocal
G(Global)模块级别(文件顶部)全局变量global
B(Built-in)Python 内置对象—

💡 记忆口诀:L → E → G → B(由内向外,依次寻找)


1.2 局部作用域

在函数内部定义的变量,称为局部变量,只在函数内部有效:

def test():local_var="我是局部变量"print(local_var)test()# print(local_var)  # ❌ 报错:name 'local_var' is not defined

1.3 全局作用域

在文件顶部(函数外部)定义的变量,称为全局变量,整个文件都可以访问:

global_var="我是全局变量"def test():print(global_var)test()            # 调用函数,可以访问print(global_var) # 函数外也可以访问

输出:

我是全局变量我是全局变量

1.4 global 关键字

函数内部默认只能读取全局变量,不能直接修改:

count=10def increment():count=count+1# ❌ 报错:UnboundLocalErrorprint(count)

使用 global 关键字声明后,就可以在函数内修改全局变量:

count=10def increment():global count# 声明使用全局变量count=count+1print(count)increment()  # 11print(count)  # 11(全局变量被修改)

⚠️ 建议:尽量少用全局变量,函数之间传递参数更清晰、更安全。


1.5 nonlocal 关键字

nonlocal 用于嵌套函数中,修改外层(非全局)函数的变量:

def outer():num=10# outer 的局部变量def inner():nonlocal num# 声明使用外层函数的变量num=99print(f"inner: {num}")inner()print(f"outer: {num}")outer()

输出:

inner: 99outer: 99

如果去掉 nonlocal,inner 内部创建一个新的局部变量,原有 num 不受影响:

def outer():num=10def inner():num=99# 这里创建的是局部变量,不影响外层print(f"inner: {num}")inner()print(f"outer: {num}")  # 仍是 10outer()

输出:

inner: 99outer: 10

1.6 作用域综合对比

关键字作用范围可读可写
不声明局部变量✅✅(创建新局部变量)
global全局变量✅✅
nonlocal外层函数变量✅✅

2. 递归函数

2.1 什么是递归?

递归就是函数自己调用自己。就像俄罗斯套娃,一个套着一个,直到最小的那一个为止。

递归由两部分组成:

  • 递归出口:什么时候停止(最基础的情况)

  • 递归调用:函数继续调用自己


2.2 递归计算阶乘

需求:计算 n! = n × (n-1) × (n-2) × ... × 1

递归分析:

  • 递归出口:n = 1 时,返回 1

  • 递归调用:n! = n × (n-1)!

# 普通实现def factorial(n):result = 1for i in range(1, n+1):result *= ireturn result# 递归实现def factorial_recursive(n):if n == 1:return 1# 递归出口return n*factorial_recursive(n-1)  # 递归调用print(factorial_recursive(5))  # 120

递归调用过程(n=5):

factorial_recursive(5)  → 5 * factorial_recursive(4)      → 4 * factorial_recursive(3)          → 3 * factorial_recursive(2)              → 2 * factorial_recursive(1)                  → 1  ← 递归出口          → 2 * 1 = 2      → 3 * 2 = 6  → 4 * 6 = 24→ 5 * 24 = 120

2.3 递归实现斐波那契数列

斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, ...

规律:F(n) = F(n-1) + F(n-2),且 F(1)=1, F(2)=1

def fibonacci_iter(n):if n in (1, 2):return 1a, b=1, 1for _ in range(3, n+1):c=a+ba=bb=creturn b# 输出前10个斐波那契数for i in range(1, 11):print(f"F({i}) = {fibonacci_iter(i)}")

输出:

F(1) = 1F(2) = 1F(3) = 2F(4) = 3F(5) = 5F(6) = 8F(7) = 13F(8) = 21F(9) = 34F(10) = 55

2.4 递归的注意事项

⚠️ 递归必须设定出口,否则会导致无限递归,引发 RecursionError。

# 危险:无递归出口def bad_recursive(n):return n+bad_recursive(n-1)# bad_recursive(5)  # ❌ RecursionError: maximum recursion depth exceeded

递归 vs 循环:

维度递归循环
代码简洁度✅ 更简洁一般
性能较差(函数调用开销)✅ 更高
内存占用较高(调用栈)✅ 更低
适用场景问题本身具有递归结构一般迭代问题

💡 建议:能用循环解决的问题,优先用循环。递归适合树形结构、分治等问题。


2.5 递归的优化——记忆化

上述斐波那契递归有大量重复计算,可以用记忆化(Memoization)优化:

# 使用字典手动记忆化memo= {}def fib(n):# 递归出口:第1、2项都是 1if n<=2:return1# 如果已经算过,直接从缓存拿,不用再算if n in memo:return memo[n]# 没算过就计算,并存入缓存result = fib(n-1) +fib(n-2)memo[n] = result# 存起来return result# 输出前10项for i in range(1, 11):print(f"F({i}) = {fibonacci_iter(i)}")

下篇继续讲解函数进阶:闭包与装饰器,教你如何封装自己的代码。

Python入门必看:Python函数基础精讲(上篇)

最新文章

随机文章