什么是闭包
在Python中,闭包(Closure)是指一个函数(称为内部函数)捕获了其外部作用域中的变量,并且可以在其内部函数范围之外被调用。换句话说,闭包可以访问其定义时所处环境中的变量,即使在其定义之后这些变量的作用域已经消失了。
闭包的代码结构
1 2 3 4 5 6 7 8 9 10 11
| def send_message(message): def print_message(): print(message)
return print_message
func_obj = send_message('python天下第一...') func_obj()
|
上面这段代码是闭包的基本结构,在send_message函数的内部定义了一个print_message函数,send_message函数返回的是内部函数print_message的地址,并且print_message函数可以访问到外部函数send_message的形式参数。func_obj = send_message(‘python天下第一…’),这一段代码是将send_message函数中的内部函数print_message的函数地址值赋值给了func_obj,所以func_obj()实际上就是执行了内部函数print_message。
利用闭包的特性完成代码的复用性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| def create_calculator(operation): def add(x, y): return x + y
def subtract(x, y): return x - y
def multiply(x, y): return x * y
def divide(x, y): if y != 0: return x / y else: return "Error: Division by zero!"
if operation == "add": return add elif operation == "subtract": return subtract elif operation == "multiply": return multiply elif operation == "divide": return divide else: return None
add_calculator = create_calculator("add") result = add_calculator(5, 3) print(result)
subtract_calculator = create_calculator("subtract") result = subtract_calculator(10, 4) print(result)
multiply_calculator = create_calculator("multiply") result = multiply_calculator(7, 2) print(result)
divide_calculator = create_calculator("divide") result = divide_calculator(8, 2) print(result)
|
在上面的代码中,create_calculator函数返回了不同的内部函数(add、subtract、multiply、divide),这些内部函数捕获了外部函数中的变量operation。通过调用create_calculator并传递不同的操作类型,我们可以创建不同功能的计算器,实现了代码的复用。
修改闭包中的形式参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def counter(start=0): def add(): nonlocal start start += 1 return start
return add
obj = counter(10) print(obj())
""" global: 作用于不可变对象且这个对象是一个全局的 nonlocal: 作用于不可变对象且这个对象具有作用域的 """
|
在上面这段代码中,我们定义了一个函数counter,在函数counter的内部定义了一个函数add,内部函数可以访问到外部函数的形式参数,但是如果内部函数想要修改外部函数的形式参数那就必须使用nonlocal关键字。
多个闭包是内存隔离的
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def wrapper(name): def message(content): print(f'{name}: {content}')
print(f'内部函数引用的地址为:', id(message)) return message
func_1 = wrapper('安娜') func_2 = wrapper('双双')
print(id(func_1)) print(id(func_2))
|