提升Python函数编程效率的关键技巧与策略(进阶篇)
目录
函数的参数
Python 函数参数可分为以下 4 种类型:编辑
参数使用详解
1. 位置参数 (Positional Arguments)
2. 默认参数 (Default Arguments)
3. 可变参数 (可变长度参数)
参数传递机制
Python 的参数传递是 对象引用传递:
⚠️ 关键注意事项
默认参数的陷阱:默认值在函数定义时计算一次(若默认值是可变对象可能引发意外)
参数顺序规则:必须按以下顺序定义参数:
强制关键字参数(Python 3.8+):用 * 分隔
高级技巧
1. 参数解包
2. 类型提示(Python 3.5+)编辑
📊 参数类型对比表编辑
函数嵌套
🎯 核心作用编辑
🔧 基础用法
1. 简单嵌套
2. 闭包(保留外部变量)
🌟 典型应用场景
① 封装私有逻辑编辑
② 装饰器实现
③ 工厂模式生成函数
🚩 关键注意事项
1.作用域规则:内层函数可读取外层变量,但修改需用 nonlocal 声明
2.内存占用:闭包会保留外层函数变量的引用,可能影响内存回收
💡 进阶技巧
1. 多层嵌套实现状态机
2. 类替代方案(类似闭包的效果)
接着上一节
函数的参数
在 Python 中,函数参数是向函数传递数据的桥梁,它让函数可以接收外部输入,实现灵活的逻辑处理。参数的设计直接影响函数的灵活性和易用性,以下是详细解析:
Python 函数参数可分为以下 4 种类型:
参数使用详解
1. 位置参数 (Positional Arguments)
必须按定义顺序传递
数量必须匹配
def greet(name, greeting):
print(f"{greeting}, {name}!")
greet("Alice", "Hello") # 正确:Hello, Alice!
# greet("Hi") # 错误:缺少参数
2. 默认参数 (Default Arguments)
参数可省略(使用默认值)
默认参数必须定义在非默认参数之后
def order_coffee(type="美式", size="中杯"):
print(f"{size}{type}咖啡")
order_coffee() # 输出:中杯美式咖啡
order_coffee("拿铁", "大杯") # 输出:大杯拿铁咖啡
order_coffee(size="超大杯") # 输出:超大杯美式咖啡
3. 可变参数 (可变长度参数)
*args
:接收额外位置参数(元组)
**kwargs
:接收额外关键字参数(字典)
def demo_args(a, *args, **kwargs):
print(f"固定参数: {a}")
print(f"可变位置参数: {args}")
print(f"可变关键字参数: {kwargs}")
demo_args(1, 2, 3, name="Alice", age=20)
# 输出:
# 固定参数: 1
# 可变位置参数: (2, 3)
# 可变关键字参数: {'name': 'Alice', 'age': 20}
参数传递机制
Python 的参数传递是 对象引用传递:
不可变对象(数字、字符串、元组):函数内修改不会影响原始值
可变对象(列表、字典):函数内修改会影响原始值
示例对比
def modify(num, lst):
num += 1 # 新创建整数对象
lst.append(4) # 修改原列表
x = 10
y = [1, 2, 3]
modify(x, y)
print(x) # 输出 10(未变)
print(y) # 输出 [1, 2, 3, 4](已修改)
⚠️ 关键注意事项
默认参数的陷阱:默认值在函数定义时计算一次(若默认值是可变对象可能引发意外)
# 错误写法(默认值为列表)
def buggy(a, lst=[]):
lst.append(a)
return lst
print(buggy(1)) # [1]
print(buggy(2)) # [1, 2](会保留之前的值!)
# 正确改进(用 None 替代)
def fixed(a, lst=None):
lst = [] if lst is None else lst
lst.append(a)
return lst
参数顺序规则:必须按以下顺序定义参数:
def func(位置参数, 默认参数, *args, **kwargs)
强制关键字参数(Python 3.8+):用 *
分隔
def strict_args(a, *, b, c): # b和c必须用关键字传递
return a + b + c
strict_args(1, b=2, c=3) # 正确
# strict_args(1, 2, 3) # 报错
高级技巧
1. 参数解包
列表/元组解包:用 *
展开为位置参数
字典解包:用 **
展开为关键字参数
2. 类型提示(Python 3.5+)
📊 参数类型对比表
函数嵌套
Python 中的 函数嵌套 是指在一个函数内部定义另一个函数,这种结构常用于 封装特定逻辑、创建闭包 或 实现装饰器。嵌套函数可以访问外部函数的变量,形成独特的变量作用域关系,是 Python 灵活性的重要体现。
🎯 核心作用
🔧 基础用法
1. 简单嵌套
def outer():
print("外层函数执行")
def inner(): # 内部函数定义
print("内层函数执行")
inner() # 在 outer 内部调用
outer()
# 输出:
# 外层函数执行
# 内层函数执行
2. 闭包(保留外部变量)
def counter():
count = 0 # 外层变量
def add(): # 闭包函数
nonlocal count # 声明使用外层变量
count += 1
return count
return add # 返回内部函数对象
c = counter()
print(c()) # 1
print(c()) # 2(记住之前的状态)
🌟 典型应用场景
① 封装私有逻辑
② 装饰器实现
def logger(func):
"""记录函数执行时间的装饰器"""
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs) # 执行原函数
print(f"{func.__name__} 耗时 {time.time()-start:.2f}秒")
return result
return wrapper
@logger
def heavy_task():
time.sleep(1)
heavy_task() # 输出:heavy_task 耗时 1.00秒
③ 工厂模式生成函数
def power_factory(exponent):
"""创建计算次方的函数"""
def calculate(base):
return base ** exponent
return calculate
square = power_factory(2)
cube = power_factory(3)
print(square(5)) # 25
print(cube(3)) # 27
🚩 关键注意事项
1.作用域规则:内层函数可读取外层变量,但修改需用 nonlocal
声明
def outer():
x = 10
def inner():
nonlocal x # 必须声明才能修改
x += 1
print(x)
inner() # 输出 11
2.内存占用:闭包会保留外层函数变量的引用,可能影响内存回收
# 创建大量闭包时需注意内存管理
def create_closures():
return [lambda: i for i in range(3)] # 所有lambda都引用最终i值(2)
funcs = create_closures()
print([f() for f in funcs]) # 输出 [2, 2, 2]
# 正确写法(立即绑定当前值)
def fixed_closures():
return [lambda x=i: x for i in range(3)]
💡 进阶技巧
1. 多层嵌套实现状态机
def game_controller():
score = 0
def add_points(p):
nonlocal score
score += p
print(f"当前分数:{score}")
def reset():
nonlocal score
score = 0
print("分数已重置")
return add_points, reset # 返回多个闭包函数
add, reset = game_controller()
add(5) # 当前分数:5
add(3) # 当前分数:8
reset() # 分数已重置
2. 类替代方案(类似闭包的效果)
class Counter:
def __init__(self):
self.count = 0
def __call__(self): # 使实例可像函数一样调用
self.count += 1
return self.count
c = Counter()
print(c()) # 1
print(c()) # 2
今天先看到这,接下来会更精彩
作者:Multiple-ji