Python--函数高级(上)
1. 函数嵌套
1.1 作用域与函数定义
Python以函数为作用域,内部数据只能被当前作用域或子作用域访问。
NAME = "全局变量"
def outer():
def inner():
print(NAME) # 访问全局变量
inner()
outer() # 输出:全局变量
关键点:
- 函数查找变量时遵循 LEGB规则(Local → Enclosing → Global → Built-in)
- 函数定义的位置影响作用域(全局/局部)
1.2 嵌套函数的作用域问题
示例1:变量查找顺序
def outer():
name = "外层变量"
def inner():
print(name) # 优先查找外层作用域
return inner
func = outer()
func() # 输出:外层变量
示例2:变量动态绑定
def outer():
funcs = []
for i in range(3):
def inner():
print(i)
funcs.append(inner)
return funcs
f1, f2, f3 = outer()
f1() # 输出2(闭包捕获的是变量i的最终值)
1.3 应用场景
- 封装功能:将内部函数隐藏在父函数中,避免全局命名冲突。
- 代码复用:拆分复杂功能为多个嵌套函数。
# 生成验证码示例
def create_code():
import random
def generate_chars():
# 生成随机字符
return random.sample("ABCDEFG", 4)
def add_noise(image):
# 添加干扰线/点
pass
code = generate_chars()
add_noise(code)
return code
2. 闭包
2.1 闭包的定义
闭包是由函数及其相关引用环境组合而成的实体,能捕获并保存外部作用域的变量。
def outer(msg):
def inner():
print(msg) # 捕获外部变量msg
return inner
closure = outer("Hello")
closure() # 输出:Hello
闭包三要素:
- 嵌套函数
- 内部函数引用外部变量
- 外部函数返回内部函数
2.2 应用场景
场景1:封装私有数据
def counter():
count = 0
def add():
nonlocal count
count += 1
return count
return add
c = counter()
print(c(), c(), c()) # 输出:1 2 3
场景2:延迟执行
def download(url):
def handler():
# 实际下载逻辑
print(f"下载完成:{url}")
return handler
task = download("https://example.com")
task() # 在需要时执行