【第八章】函数进阶宝典:参数、返回值与作用域全解析
函数是 Python 最重要的抽象单元,灵活掌握参数定义、返回值处理和作用域规则,才能写出高复用、高可维护的代码。深入解析各类参数、返回技巧与作用域关键字,让你的函数设计更加优雅!
目录
- 前言
- 参数类型全家桶
- 位置参数
- 关键字参数
- 默认参数
- 可变参数
*args
- 关键字可变参数
**kwargs
- 仅限关键字参数
- [仅限位置参数(Python 3.8+)](#仅限位置参数python 38)
- 返回值与多返回
- 作用域与命名空间
- 局部作用域 (Local)
- 全局作用域 (Global)
- 内嵌作用域 (Enclosing) 与
nonlocal
- 内置作用域 (Built-in)
- 闭包与装饰器前奏
- 实战示例
- 统计函数调用日志
- 工厂函数生成定制化函数
- 总结
- 免责声明
前言
在 Python 中,函数定义远不止 (x, y)
这么简单。掌握多种参数形式、返回值解包,以及作用域规则,能让你的函数在团队协作和框架开发中大放异彩。本文将全面拆解函数高级用法,并通过实战案例加深理解。
参数类型全家桶
位置参数
def add(a, b):return a + bprint(add(1, 2)) # 3
- 按顺序传入,缺少必报错。
关键字参数
def greet(name, msg):print(f"{name},{msg}")greet(msg="早上好", name="Alice")
- 可指定参数名,顺序可任意。
默认参数
def connect(host, port=3306):print(f"连接到 {host}:{port}")connect("localhost") # 使用默认 port
connect("localhost", 5432) # 覆盖默认值
- 默认值在函数定义时计算,避免可变对象陷阱。
可变参数 *args
def concat(*args):return "-".join(args)print(concat("A", "B", "C")) # "A-B-C"
- 接收任意数量的位置参数,
args
为元组。
关键字可变参数 **kwargs
def show_info(**kwargs):for k, v in kwargs.items():print(f"{k} = {v}")show_info(name="Bob", age=30)
- 接收任意数量的命名参数,
kwargs
为字典。
仅限关键字参数
def func(a, *, b, c=10):print(a, b, c)func(1, b=2) # c 使用默认
# func(1, 2) # 报错:b 必须以关键字形式传入
*
之后的参数必须使用关键字传递。
仅限位置参数(Python 3.8+)
def fn(a, b, /, c, d):print(a, b, c, d)fn(1, 2, c=3, d=4)
# fn(a=1, b=2, c=3, d=4) # 报错:a、b 必须位置传入
/
之前的参数只能位置传递。
返回值与多返回
def stats(numbers):total = sum(numbers)count = len(numbers)return total, count, total/countt, n, avg = stats([10, 20, 30])
print(f"{t=}, {n=}, {avg=}")
- Python 实际返回元组,支持解包;也可
return
单值或None
。
作用域与命名空间
局部作用域 (Local)
函数内部定义的变量,默认只在该函数内可见。
def foo():x = 5 # 局部变量print(x)
全局作用域 (Global)
模块层级定义的变量,可在函数内阅读,但修改需使用 global
。
x = 10def bar():global xx += 5bar()
print(x) # 15
内嵌作用域 (Enclosing) 与 nonlocal
当函数定义在另一个函数内部,可访问外层变量,修改需 nonlocal
。
def outer():count = 0def inner():nonlocal countcount += 1print(count)return innerf = outer()
f() # 1
f() # 2
内置作用域 (Built-in)
Python 内置函数和异常构成的最顶层作用域。
闭包与装饰器前奏
闭包 = 能访问外层作用域变量的函数,装饰器常基于闭包实现。
def make_multiplier(n):def multiplier(x):return x * nreturn multiplierdouble = make_multiplier(2)
print(double(5)) # 10
实战示例
1. 统计函数调用日志
def log_calls(func):def wrapper(*args, **kwargs):print(f"调用 {func.__name__},args={args}, kwargs={kwargs}")result = func(*args, **kwargs)print(f"返回值:{result}")return resultreturn wrapper@log_calls
def add(a, b):return a + badd(3, 4)
2. 工厂函数生成定制化函数
def power_factory(exp):def power(x):return x ** expreturn powersquare = power_factory(2)
cube = power_factory(3)
print(square(5)) # 25
print(cube(5)) # 125
总结
- 参数形式多样:位置、关键字、默认、可变、仅关键字/仅位置,灵活配置函数接口。
- 返回值可打包解包,支持多值返回。
- 作用域规则:四层命名空间(LEGB),
global
和nonlocal
用于修改外层变量。 - 掌握闭包与装饰器前奏,为后续进阶开发打下基础。
免责声明
本文示例仅供学习交流,请在受控环境中测试后再投入生产使用。作者对因使用本文内容引发的任何损失不承担责任,转载请注明出处。