7. 装饰器的嵌套装饰
目标
使用装饰器,对银行存钱(savemoney)和取钱(withdraw)业务的实际操作函数成功调用后模拟发送短信息。
对一个函数可以添加多个装饰器。
装饰器的嵌套装饰的语法
@装饰器n <换行>
...
@装饰器2 <换行>
@装饰器1 <换行>
def 被装饰函数名(形参列表):
语句块
说明
- 距离被装饰函数最近的装饰器被优先装饰,如上面语法所示:
- 装饰器1最先替换被装饰函数名绑定的函数。
- 装饰器2再替换被装饰函数名绑定的函数。以此类推。
上述语法等价于
@装饰器n <换行>
...
@装饰器2 <换行>
@装饰器1 <换行>
def 被装饰函数名(形参列表):
语句块
# 等价于
被装饰函数名 = 装饰器2(装饰器1(被装饰函数名))
示例
# 此示例示意 装饰器的嵌套装饰 的用法
bank_account = {
'魏明择': {'password': '123456', 'money': 500},
'小张': {'password': '654321', 'money': 10000},
}
def message_send(fn):
def wrap(name, x):
r = fn(name, x)
print(name, '您办理了银行的业务,短息发送中...')
return r
return wrap
def privileged_check(fn):
'权限管理装饰器'
def wrap(name, x):
if name not in bank_account:
raise ValueError(f'账户异常')
password = input(f'请输入{name}的密码: ')
if password != bank_account[name]['password']:
raise ValueError(f'账户异常')
return fn(name, x)
return wrap
@message_send
@privileged_check
def savemoney(name, x): # 存钱
bank_account[name]['money'] += x
print(name, "存钱", x, "元。")
@privileged_check
def withdraw(name, x): # 取钱
bank_account[name]['money'] -= x
print(name, "取钱", x, "元。")
print('原来的银行账户:', bank_account)
savemoney("魏明择", 200)
savemoney("小张", 20000)
withdraw("魏明择", 300)
print('现在的银行账户:', bank_account)
上述程序实现了对savemoney 添加了 权限管理的装饰器 privileged_check 后,又添加了 message_send装饰器。