5. Python 高级特性
5.1 装饰器与闭包
5.1.1 闭包的概念与实现
闭包(Closure)是 Python 中一个强大的特性,它允许函数在其定义的作用域之外访问和操作变量。闭包的核心思想是:一个函数可以“记住”并访问它被定义时的环境,即使这个函数在其定义环境之外被调用。
闭包的实现依赖于 Python 的作用域规则和函数的嵌套定义。以下是一个简单的闭包示例:
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(10)
print(closure(5)) # 输出 15
在这个例子中,inner_function 是一个闭包,它“记住”了 outer_function 中的变量 x,即使 outer_function 已经执行完毕。
5.1.2 装饰器的基本概念
装饰器(Decorator)是 Python 中用于修改或扩展函数行为的一种高级技术。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。装饰器通常用于在不修改原函数代码的情况下,为函数添加额外的功能。
以下是一个简单的装饰器示例:
def my_decorator(func):
def wrapper():
print("在函数执行之前")
func()
print("在函数执行之后")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
在这个例子中,my_decorator 是一个装饰器,它修改了 say_hello 函数的行为,使其在执行前后分别打印一条消息。
5.1.3 装饰器的应用场景
装饰器在 Python 中有广泛的应用场景,包括但不限于:
- 日志记录:在函数执行前后记录日志信息。
- 权限验证:在函数执行前检查用户权限。
- 性能测试:测量函数的执行时间。
- 缓存:缓存函数的返回值,避免重复计算。
以下是一个用于测量函数执行时间的装饰器示例:
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} 执行时间: {end_time - start_time} 秒")
return result
return wrapper
@timing_decorator
def slow_function():
time.sleep(2)
slow_function()
5.1.4 装饰器的嵌套与参数化
装饰器可以嵌套使用,也可以接受参数。嵌套装饰器的执行顺序是从下往上,即最内层的装饰器最先执行。以下是一个嵌套装饰器的示例:
def decorator1(func):
def wrapper():
print("装饰器 1")
func()
return wrapper
def decorator2(func):
def wrapper():
print("装饰器 2")
func()
return wrapper
@decorator1
@decorator2
def say_hello():
print("Hello!")
say_hello()
参数化装饰器允许装饰器接受额外的参数,从而更灵活地控制装饰器的行为。以下是一个参数化装饰器的示例:
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
5.1.5 闭包与装饰器的结合
闭包和装饰器可以结合使用,以实现更复杂的功能。例如,可以使用闭包来保存装饰器的状态,或者使用装饰器来修改闭包的行为。
以下是一个结合闭包和装饰器的示例:
def counter_decorator(func):
count = 0
def wrapper(*args, **kwargs):
nonlocal count
count += 1
print(f"函数 {func.__name__} 被调用了 {count} 次")
return func(*args, **kwargs)
return wrapper
@counter_decorator
def say_hello():
print("Hello!")
say_hello()
say_hello()
在这个例子中,counter_decorator 使用闭包来保存函数调用的次数,并在每次调用时打印出来。
5.1.6 总结
闭包和装饰器是 Python 中非常强大的高级特性,它们可以帮助开发者编写更加灵活和可重用的代码。通过理解闭包的概念和装饰器的实现方式,开发者可以在实际项目中更好地利用这些特性,提升代码的质量和可维护性。
