一、闭包
闭包(Closure)是编程语言中一个重要的概念,尤其在函数式编程语言中。闭包允许一个函数访问其外部作用域中的变量,即使这个函数在外部作用域之外被调用。
闭包的定义
闭包是一个函数,它记住了创建它的外部作用域中的变量。换句话说,闭包可以访问其创建时所在作用域的变量,即使这个作用域的代码已经执行完毕。
1、外部函数嵌套内部函数
2、调用外部函数 返回内部函数
3、内部函数可以调用 外部函数定义的变量 以及 声明的参数
闭包的组成部分
- 函数:闭包本身是一个函数。
- 外部作用域的变量:闭包可以访问并可能修改这些变量。
闭包的用途
- 数据封装:闭包可以用于封装数据和操作这些数据的函数,类似于对象。
- 延迟计算:闭包可以延迟执行某些计算,直到实际需要结果时。
- 回调函数:在事件驱动编程中,闭包常用于定义回调函数,携带额外的参数。
- 柯里化:闭包可以用于实现函数的部分应用或柯里化。
- 装饰器:装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数
Python中的闭包示例
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(2)
print(closure(3)) # 输出: 5
outer_function
是一个函数,它接受一个参数x
。inner_function
是一个嵌套函数,它接受一个参数y
并返回x + y
。outer_function
返回inner_function
。- 当
outer_function(2)
被调用时,它返回一个闭包closure
,这个闭包记住了x
的值(即2)。 - 当调用
closure(3)
时,闭包访问并使用了x
的值(2),计算并返回结果5。
二、装饰器
定义
装饰器(decorators)是 Python 中的一种高级功能,它允许你动态地修改函数或类的行为,本质是一个闭包函数。它允许程序员在不修改原始函数代码的情况下给函数添加新的功能。
基本语法
def my_decorator(func):
def wrapper(*args, **kwargs):
# 在调用原始函数之前可以做一些事情
print("Something before the function is called.")
# 调用原始函数
result = func(*args, **kwargs)
# 在调用原始函数之后可以做一些事情
print("Something after the function is called.")
return result
return wrapper
使用装饰器
使用装饰器非常简单,只需要在函数定义之前使用 @
符号加上装饰器的名称即可:
@my_decorator
def say_hello():
print("Hello!")
say_hello()
当调用 say_hello()
函数时,实际上是调用了 my_decorator(say_hello)
返回的 wrapper
函数。
参数装饰器
如果被装饰的函数需要参数,装饰器也需要相应地处理这些参数:
def my_decorator_with_params(func):
def wrapper(x, y):
print(f"The numbers are: {x} and {y}")
result = func(x, y)
return result
return wrapper
@my_decorator_with_params
def add(x, y):
return x + y
print(add(5, 3))
# 输出: The numbers are: 5 and 3
# 8
带参数的装饰器
装饰器本身也可以有参数,这种情况下需要定义一个外层函数,它接收装饰器的参数,并返回一个装饰器:
def decorator_with_args(arg):
def actual_decorator(func):
def wrapper(*args, **kwargs):
print(f"Decorator argument: {arg}")
return func(*args, **kwargs)
return wrapper
return actual_decorator
@decorator_with_args("test")
def func():
print("Function is called.")
func()
装饰器案例
# 解决带参函数 装饰器 以排序耗时为例
import copy
import random
import time
# 推导式生成一个含有 1000 个数字的列表
data = [random.randint(1, 1000) for i in range(1000)]
# 深层拷贝
data_copy = copy.deepcopy(data)
# time.time()获取当前 时间戳 函数前后 各写一个 两者差值既是程序运行时间
def time_cost(f):
def calc(tf):
start = time.time()
f(tf)
print(f"{f.__name__} 时间消耗 {time.time() - start}")
return calc
# sort() 列表排序函数 默认 reverse=False 升序 当 reverse=True 时 降序
@time_cost
def sort_data(tf):
data.sort(reverse=tf)
print(data)
# sorted() 内置函数 默认 reverse=False 升序 当 reverse=True 时 降序 返回一个新列表
@time_cost
def sort_data_copy(tf):
new_data = sorted(data_copy, reverse=tf)
print(new_data)
sort_data(False)
sort_data_copy(True)
![](https://i-blog.csdnimg.cn/direct/b529d5f8b33f48ae9cedec5d04410465.png)