作用,隐藏部分的功能,让访问者不干涉内部的执行
语法:
def 外部函数([参数]): def 内部函数([参数]): 业务逻辑 return 闭包函数 # 通过函数得到闭包函数 fn = 外部函数() fn() # 调用闭包函数执行内部逻辑
普通闭包的演示
def outer(logo: str):
def inner(msg: str):
print(f'<{logo}>{msg}<{logo}>')
return inner
fn = outer('alibaba')
fn('电商')
fn('Java')
"""
<alibaba>电商<alibaba>
<alibaba>Java<alibaba>
"""
ATM案例的改造
def account_create(init_amount=0):
def atm(num, deposit=True):
# 闭包中修改外部函数的值,通过关键字 nonlocal 实现
nonlocal init_amount
if deposit:
init_amount += num
print(f'存款:+{num},账户余额:{init_amount}')
else:
init_amount -= num
print(f'取款:-{num},账户余额:{init_amount}')
return atm
ac = account_create()
ac(100)
ac(300)
ac(200, False)
nonlocal 关键字
在闭包中,内部函数如果需要对外部函数的值进行修改,需要通过该关键字指定
如
atm
中,内部函数中定义了nonlocal init_amount
表明在atm
内部函数需要修改account_create
的入参
def use_nonlocal(init_unm=0):
def add(x: int, y: int):
nonlocal init_unm
# 每次计算后,将值赋给 init_num 缓存
init_unm += x + y
print(f'init_num={init_unm}')
return add
f = use_nonlocal()
f(1, 2) # 3
f(1, 2) # 6
f(1, 2) # 9
装饰器:基础写法
"""
装饰器:
通过装饰器来对函数进行增强
以下案例:
使用 2g 网络打电话
增强:开启 5g 网络打电话
"""
# 增强通话,启动 5g 通话
def enhance(fn):
def enable_5g():
print('开启 5g 通话 ...')
fn()
print('关闭 5g 通话 ...')
return enable_5g
# 使用 2g 网络打电话
def call_2g():
import time
import random
print('开始打电话 ....')
time.sleep(random.randint(0, 5))
print('结束打电话 ....')
en = enhance(call_2g)
en()
装饰器:高级写法
# 增强通话,启动 5g 通话
def enhance(fn):
def enable_5g():
print('开启 5g 通话 ...')
fn()
print('关闭 5g 通话 ...')
return enable_5g
# 通过 @函数名 来装饰该函数
@enhance
def call_2g():
import time
import random
print('开始打电话 ....')
time.sleep(random.randint(0, 5))
print('结束打电话 ....')
call_2g()