装饰器

发布时间 2023-12-29 08:48:29作者: dhyuannn

装饰器

  • 装饰 代指为被装饰对象添加新的功能, 代指器具/工具,装饰器与被装饰的对象均可以是任意可调用对象。

【一】装饰器的作用

  • 软件的设计应该遵循开放封闭原则,即对扩展是开放的,而对修改是封闭的。

【二】装饰器的分类

  • 函数装饰器分为:无参装饰器和有参装饰器

【三】无参装饰器

(1)无参装饰器

def outer(func):
    def inner(*args,**kwargs):
        res = func(*args,**kwargs)
        return res
    return inner
@outer
def add(*args,**kwargs):
    return 1
print(add())

(2)练习

user_data = {'dhy': 20} 
def outer(func):
    def inner(*args,**kwargs):
            if user_data['dhy']>=18:
                res=func()
                return res
            else:
                return False,'18禁!'
    return inner
 
def watch(*args,**kwargs):
    return True,'
 
watch=outer(watch)
print(watch())
 
 
@outer 
def watch(*args,**kwargs):
    return True,'
print(watch())

【四】有参装饰器

  • 本质上就是在无参装饰器外面再套一层函数,再判断他的tag条件

    示例:取钱

user_data = {'username': 'dhy', 'password': '0703'}
bank_data = {'dream': {'pay_pwd': '521', 'balance': 1000}}

# 先验证登录
# 再验证 输入的金额 --- 符合数字 / 余额充足

def outer(func):
    def inner(*args, **kwargs):
        username=input('输入用户名:')
        password=input('输入密码:')

        if username == user_data.get('username') and password == user_data.get('password'):
            print("登录成功!")
            return func(*args, **kwargs)
        else:
            print('用户名或密码错误,登录失败')
            return None

    return inner

    # 校验登录
    # 校验金额  符合数字 / 余额充足 --- 把金额通过装饰器 返回来
    # 拿着你的金额进行提款
    ...
def check_amount(func):
    def inner(*args, **kwargs):
        amount = input("请输入取款金额: ")
        if not amount.isdigit():
            print('请重新输入数字')
            return None
        user = bank_data.get(user_data['username'])
        if int(amount) > user.get('balance'):
            print('余额不足')
            return None
        return func(amount, *args, **kwargs)
    return inner
@outer
@check_amount
def money(amount):
    user = bank_data[user_data['username']]
    user['balance'] -= int(amount)
    print(f"成功取款 {amount} 元,当前余额为 {user['balance']} 元。")
money()

【五】伪装装饰器

from functools import wraps
def wrapper(func):
    def inner(*args, **kwargs):
        '''
        # 这是验证登录的装饰器
            --- 确认账号是 dhy 密码是 0703 才是管理员
        '''
        return func(*args, **kwargs)
 
    return inner
 
@wrapper
def add():
    return 1 + 1
 
print(help(add))
print(f'----------------------------')
 
def wrapper(func):
    @wraps(func)
    def inner(*args, **kwargs):
        '''
        :param args: 可变长位置参数
        :param kwargs: 可变长关键字参数
        :return:
        '''
        return func(*args, **kwargs)
 
    return inner
 
@wrapper
def add():
    return 1 + 1
 
 
print(help(add))