Appearance
16|返回值与作用域
函数执行完后需要把结果交回调用方,这是返回值的作用。同时,函数内部定义的变量和外部变量是隔离的——这种隔离叫作用域。理解返回值和作用域,才能写出不互相干扰的函数。
一、return 语句
return 结束函数执行,并把值交回调用方:
python
def square(x):
return x * x
result = square(5) # result = 25没有 return 的函数返回 None:
python
def log(message):
print(f"[LOG] {message}")
value = log("done") # value = Nonereturn 后面可以没有值,表示提前结束函数:
python
def divide(a, b):
if b == 0:
return # 提前返回 None
return a / b二、返回多个值
Python 函数可以返回多个值,本质上是返回一个元组:
python
def min_max(numbers):
return min(numbers), max(numbers)
smallest, largest = min_max([3, 1, 4, 1, 5])
# smallest = 1, largest = 5只用一个变量接收,拿到的是元组:
python
result = min_max([3, 1, 4])
print(result) # (1, 4)
print(result[0]) # 1三、局部变量
函数内部定义的变量只在函数内部可见,函数外部访问不到:
python
def calculate():
value = 42 # 局部变量
return value
calculate()
print(value) # NameError: name 'value' is not defined这种隔离是好设计——函数内部的临时计算不会污染外部命名空间。
四、全局变量
函数可以读取外部变量,但要修改时需要 global 声明:
python
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # 1不加 global 直接修改:
python
counter = 0
def broken_increment():
counter += 1 # UnboundLocalErrorPython 看到函数内有赋值语句 counter += 1,就把 counter 当成局部变量。但局部变量 counter 还没定义就使用,报错。
global 能不用就不用。函数之间通过参数和返回值传递数据,比共享全局变量更清楚、更容易测试。
五、nonlocal
嵌套函数(函数内部定义函数)要修改外层函数的变量,用 nonlocal:
python
def outer():
count = 0
def inner():
nonlocal count
count += 1
return count
return inner
func = outer()
print(func()) # 1
print(func()) # 2nonlocal 和 global 的区别:
global修改模块级别的全局变量nonlocal修改外层(非全局)函数的变量
nonlocal 在闭包和装饰器中使用较多。日常脚本中很少需要嵌套函数。
六、变量查找规则 LEGB
Python 查找变量时按 LEGB 顺序:
- Local:局部作用域(当前函数内部)
- Enclosing:外层函数作用域(如果有嵌套函数)
- Global:模块级别的全局作用域
- Built-in:Python 内置作用域(如
len、print)
python
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x) # local,先找到局部变量
inner()
outer()这个规则解释了为什么函数内能读到全局变量,但修改时需要声明——读取按 LEGB 规则能找到全局的 x,但赋值时 Python 默认创建局部变量,除非用 global 声明。
七、闭包
嵌套函数记住外层函数的变量,这种机制叫闭包:
python
def make_multiplier(factor):
def multiply(x):
return x * factor # 记住外层函数的 factor
return multiply
triple = make_multiplier(3)
print(triple(5)) # 15
print(triple(10)) # 30triple 是一个函数,它"记住"了 factor = 3。每次调用 triple(x),用的都是创建它时的那个 factor。
闭包在工厂函数、回调函数、装饰器中广泛使用。
记忆锚点:return 结束函数并返回值;返回多个值本质是返回元组;局部变量只在函数内可见;修改全局变量用 global,修改外层变量用 nonlocal;变量查找顺序是 LEGB;闭包让内层函数记住外层变量;全局变量尽量少用,通过参数和返回值传递数据。