首页 > 其他分享 >装饰器

装饰器

时间:2023-12-14 21:14:59浏览次数:21  
标签:return name func kwargs balance 装饰 def

装饰器

1.装饰器

  • 再不修改被装饰对象的源代码和调用方式的的前提下为装饰对象添加额外的功能

1.1装饰器分类

  • 分为无参装饰器和有参装饰器
  • 无参装饰器
# 无参装饰器模版
def outer(func):
   def inner():
      '''这里写调用 func 函数之前的逻辑'''
      res = func()
      '''这里写调用 func 函数之后的逻辑'''
      return res
    return inner

# 语法糖调用
@outer
def add():
  return 1

# 变量赋值调用
add = outer(add)
add()

# 示例
login_user_dict = {'username': 'serein', 'is_admin': True}
user_data_dict = {'serein': {'password': 521, 'role': 'admin'},
                  'formerly': {'password': 369, 'role': 'normal'}}

def check_admin(func):
  def inner():
    if login_user_dict['username'] and login_user_dict["is_admin"]:
      res = func()
      return res
    else:
      return False,"登陆失败"
    
    return inner

@check_admin
def get_money():
  return True,"取款成功"

# 第一种调用方法
# 调用check_admin方法,传入参数get_money
get_money = check_admin(get_money)
get_money()	# get_money加()执行inner方法
print(get_money)	# 取款成功

# 第二种方法,语法糖,在get_money方法上面加@check_admin
get_money()
  • 有参装饰器
# 有参数 装饰器模版
def wrapper_func(tag):
     def wrapper(func):
         def inner(*args, **kwargs):
             # tag : 表明当前需要处理的使用函数的逻辑
             if tag == None:
                 ...
             # 正常函数内需要的逻辑
             return func(*args, **kwargs)

         return inner

     return wrapper


 @wrapper_func(tag=None)
 def add():

# 案例1 有参数多个装饰器语法糖叠加使用
user_data = {'username': 'serein', 'password': '521'}
bank_data = {'serein': {'pay_pwd': '521', 'balance': 1000}}


# 先验证登录
def login_auth(func):
    def inner(*args, **kwargs):
        if user_data['username'] and user_data['password'] == "521":
            res = func(*args, **kwargs)
            return res
        else:
            return False, "未登陆"

    return inner

# 再验证 输入的金额 ---l 符合数字 / 余额充足
def check_balance(func):
    def inner(*args, **kwargs):
        name = input("请输入姓名:》》").strip()
        balance = input("请输入金额 :>>>> ").strip()
        pay_pwd = input("请输入取款密码:》》》").strip()
        if not balance.isdigit():
            return False, "非法输入"
        balance = int(balance)
        if balance > bank_data[name]['balance']:
            return False, "余额不足"
        if pay_pwd != bank_data[name]['pay_pwd']:
            return False, "取款密码错误"
        return func(name=name, balance=balance, pay_pwd=pay_pwd, *args, **kwargs)

    return inner


def add_balance(func):
    def inner(*args, **kwargs):
        name = input("请输入姓名:》》").strip()
        password = input("请输入登陆密码:")
        balance = input("请输入充值金额 :>>>> ").strip()
        if not balance.isdigit():
            return False, "请输入数字金额"
        return func(name=name, password=password, balance=balance, *args, **kwargs)
    return inner

# # 取款函数里面
@login_auth
@check_balance
def get_balance(*args, **kwargs):
    print(kwargs)
    name = kwargs.get('name')
    balance = kwargs.get('balance')
    bank_data[name]['balance'] -= balance
    print(bank_data)

@login_auth
@add_balance
def add_balance(*args, **kwargs):
    print(kwargs)
    name = kwargs.get('name')
    balance = kwargs.get('balance')
    balance = int(balance)
    bank_data[name]['balance'] += balance
    print(bank_data)

add_balance()


# 案例2,有参数合并装饰器,语法糖叠加使用
user_data = {'username': 'serein', 'password': '521'}
bank_data = {'serein': {'pay_pwd': '521', 'balance': 1000}}


# 合并装饰器
def Decorator(tag_func=None, tag=None):
    # tag-func = login 走登陆装饰器
    if tag_func == 'login':
        def wraper(func):
            def inner(*args, **kwargs):
                if user_data['username'] and user_data['password'] == "521":
                    return func(*args, **kwargs)
                return False, "未登陆"

            return inner
        return wraper

    elif tag_func == "balance":
        def wraper(func):
            def inner(*args, **kwargs):
                name = input("请输入用户名")
                balance = input("请输入金额")
                balance = int(balance)
                pay_pwd = ''
                if tag != "add_balance":
                    pay_pwd = input("请输入密码:")
                    if pay_pwd != bank_data[name]['pay_pwd']:
                        return False, "密码错误"
                    if balance > bank_data[name]['balance']:
                        return False, '余额不足'
                return func(name=name, balance=balance, pay_pwd=pay_pwd, *args, **kwargs)
            return inner
        return wraper


# 取钱
@Decorator(tag_func='login')
@Decorator(tag_func='balance', tag='get_balance')
def get_balance(*args, **kwargs):
    print(kwargs)
    name = kwargs.get('name')
    balance = kwargs.get('balance')
    bank_data[name]['balance'] -= balance
    print(bank_data)


# 存钱
@Decorator(tag_func='login')
@Decorator(tag_func='balance', tag='add_balance')
def add_balance(*args, **kwargs):
    print(kwargs)
    name = kwargs.get('name')
    balance = kwargs.get('balance')
    balance = int(balance)
    bank_data[name]['balance'] += balance
    print(bank_data)


print(get_balance())

1.2 伪装装饰器

1.2.1查看装饰器(help)

  • 可以使用help(函数名)来查看函数的文档注释,本质就是查看函数的doc属性

    • 但对于被装饰之后的函数,查看文档注释
import time


# 定义外层函数
def wrapper(func):
    # 定义内层函数:通过参数接收外部的值
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        stop_time = time.time()
        print('run time is %s' % (stop_time - start_time))

    return inner


@wrapper
def home(name):
    '''
    home page function
    :param name: str
    :return: None
    '''
    time.sleep(5)
    print('Welcome to the home page', name)


print(help(home))
'''
打印结果:

Help on function wrapper in module __main__:

wrapper(*args, **kwargs)

None
'''
  • 在被装饰之后home=wrapper
    • 查看home.name也可以发现home的函数名确实是wrapper
    • 想要保留原函数的文档和函数名属性,需要修正装饰器
import time


# 定义外层函数
def wrapper(func):
    # 定义内层函数:通过参数接收外部的值
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        stop_time = time.time()
        print('run time is %s' % (stop_time - start_time))

    inner.__doc__ = func.__doc__
    inner.__name__ = func.__name__
    return inner


@wrapper
def home(name):
    '''
    home page function
    :param name: str
    :return: None
    '''
    time.sleep(5)
    print('Welcome to the home page', name)


print(help(home))
'''
打印结果:

Help on function home in module __main__:

home(*args, **kwargs)
    home page function
    :param name: str
    :return: None

None
'''

1.2.2 伪装装饰器

  • functools模块下提供一个装饰器wraps专门用来帮我们实现这件事
import time
from functools import wraps


# 定义外层函数
def wrapper(func):
    # 伪装内层函数
    @wraps(func)
    # 定义内层函数:通过参数接收外部的值
    def inner(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        stop_time = time.time()
        print('run time is %s' % (stop_time - start_time))

    return inner


@wrapper
def home(name):
    '''
    home page function
    :param name: str
    :return: None
    '''
    time.sleep(5)
    print('Welcome to the home page', name)


print(help(home))
'''
打印结果:

Help on function home in module __main__:

home(name)
    home page function
    :param name: str
    :return: None

None
'''

标签:return,name,func,kwargs,balance,装饰,def
From: https://www.cnblogs.com/Formerly/p/17902011.html

相关文章

  • 九、@Watch装饰器:状态变量更改通知
    @Watch应用对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量这种回调函数。@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用。@Watch在ArkUI框架内部判断数值有无更新使用的是严格相等(===),遵循严格相等规范。当在严......
  • 装饰器
    装饰器一、什么是装饰器通俗的讲就是用来装饰对象的工具,这里被装饰的对象和用来装饰的装饰器都可以可以是任意的课调用的对象概括的来讲,装饰器就是在不修改被装饰对象的源代码和调用方式的基础下为被装饰对象添加额外的功能二、装饰器的用途装饰器在装饰时,应避免修改被装......
  • 装饰器
    装饰器(一)什么是装饰器装饰:代指为被装饰对象添加新的功能。器:代指器具/工具。装饰器与被装饰对象均可以是任意可调用对象。装饰器定义:在不修改被装饰对象源代码和调用方式的前提下为呗装饰对象添加额外的功能。装饰器经常用于有切莫需求的场景插入日志、性能测试、事......
  • 装饰器
    【一】装饰器装饰器(Decorator)是一种用于修改函数或类行为的特殊函数。它可以在不修改原始函数或类定义的情况下,通过添加额外的功能或行为来扩展其功能。装饰器的主要作用是增强函数或类的功能,常见的应用场景包括:函数装饰器:函数装饰器可以在不修改原函数代码的情况下,对函数进行......
  • Python高级之装饰器
    装饰器【一】装饰器介绍装饰器的由来软件的设计应该遵循开放封闭原则,即对扩展是开放的,而对修改是封闭的。对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。对修改封闭,意味着对象一旦设计完成,就可以独立完成其工作,而不要对其进行修改。软件包......
  • 装饰器模式
    装饰器,顾名思义,一个是待装饰者,一个是装饰者,就像我们早餐吃的煎饼,煎饼是待装饰者,其他的火腿、里脊、土豆丝、生菜等都是装饰者,但最终都没有改变这还是一个煎饼。这里代码上有两个重要的点,一个是装饰者会也会继承或者实现被装饰者,第二是装饰者的构造函数会有一个类型为待装饰者的参......
  • 装饰器
    装饰器装饰器的作用就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能装饰器经常用于有切面需求的场景插入日志、性能测试、事务处理、缓存、权限校验等应用场景有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用【一】装饰......
  • 装饰器
    装饰器装饰器的作用就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能装饰器经常用于有切面需求的场景插入日志、性能测试、事务处理、缓存、权限校验等应用场景有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用【一】装饰......
  • [-007-]-Python3+Unittest+Selenium Web UI自动化测试之@property装饰器默认值设置
    看示例:#!/usr/bin/python3#coding:utf-8__author__='csjin'#定义@property装饰器classPPTListModels(object):def__init__(self):self._tab_name="PPT模板"@propertydefhandle(self):returnself.__handle......
  • 【python基础之装饰器】---装饰器
    title:【python基础之装饰器】---装饰器date:2023-12-1118:54:06updated:2023-12-1214:30:00description:cover:https://home.cnblogs.com/u/dream-ze/【一】什么是装饰器装饰代指为被装饰对象添加新的功能,器代指器具/工具,装饰器与被装饰的对象均可......