首页 > 其他分享 >装饰器

装饰器

时间:2023-12-11 18:34:54浏览次数:27  
标签:return dict inner func 装饰 def user

装饰器

【一】什么是装饰器

  • 装饰 代指为被装饰对象添加新的功能代指器具/工具,装饰器与被装饰的对象均可以是任意可调用对象。
  • 概括地讲,装饰器的作用就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。
  • 装饰器经常用于有切面需求的场景
    • 插入日志、性能测试、事务处理、缓存、权限校验等应用场景
    • 装饰器是解决这类问题的绝佳设计
    • 有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

【二】装饰器的作用

  • 软件的设计应该遵循开放封闭原则,即对扩展是开放的,而对修改是封闭的。
    • 对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
    • 对修改封闭,意味着对象一旦设计完成,就可以独立完成其工作,而不要对其进行修改。
  • 软件包含的所有功能的源代码以及调用方式,都应该避免修改,否则一旦改错,则极有可能产生连锁反应,最终导致程序崩溃
    • 而对于上线后的软件,新需求或者变化又层出不穷,我们必须为程序提供扩展的可能性,这就用到了装饰器。

【三】装饰器的分类

  • 函数装饰器分为:无参装饰器和有参装饰两种
  • 二者的实现原理一样,都是’函数嵌套+闭包+函数对象’的组合使用的产物。

【四】举例

  • 闭包的使用

    def fun():
        print(f"这是fun开始")
        def inner():
            print("这是inner")
        print(f"这是fun的结束")
        #返回一个inner
        return inner
    #inner函数赋值给inner
    inner=fun()
    inner()
    
  • time.time()的使用

    import time
    def fun(func):
        start_time=time.time()
        res=func()
        print(f'总耗时 {time.time() - start_time} s')
        return True,res
    
    def function():
        print("时长为:")
        return '完成'
    #把function作为参数传递给fun函数
    result=fun(function)
    print(result)
    #输出:
    时长为:
    总耗时 0.0 s
    (True, '完成')
    
    • 登录权限案例

      login_user_dict = {'username': 'tony', 'is_admin': True}
      user_data_dict = {'tony': {'password': 123, 'role': 'admin'},
                        'hope': {'password': 789, 'role': 'normal'}}
      
      
      def check_admin(func):
          def inner(login_user_dict):
              # 验证当前是否登录并且是管理员
              if login_user_dict['username'] and login_user_dict['is_admin']:
                  # 如果是管理员 ,就正常执行我传进来的函数地址
                  res = func(login_user_dict)
                  return res
              # 重新校验
              else:
                  # 重新登录的逻辑
                  return False, '重新登录'
          return inner
      @check_admin
      def get_money(login_user_dict):
          # 取钱的前提是 : 我已经登陆过并且是管理员 ---> 验证我的登录和我的身份
          return True, f'{login_user_dict["username"]} 取了一万块'
      print(get_money(login_user_dict))
      
      
      def check_admin(func):
          def inner(*args, **kwargs):
              # 验证我当前是否登录并且是管理员
              if login_user_dict.get('username') and login_user_dict.get('is_admin'):
                  # 如果是管理员,就正常执行我传进来的函数地址
                  res = func(*args, **kwargs)
                  return True, res
              # 重新校验
              else:
                  # 重新登录的逻辑
                  return False, '重新登录'
          return inner
      
      @check_admin
      def login(username, password):
          if password == user_data_dict[username].get('password'):
              print(f'登录成功!')
          if user_data_dict[username].get('role') == 'admin':
              login_user_dict['is_admin'] = True
          else:
              login_user_dict['is_admin'] = False
          return username, password
      
      result = login('tony', '123')
      print(result)
      #(True, ('tony', '123'))
      

【五】无参装饰器模板

 def add():
     return 1
 def outer(func):
     def inner():
#         '''这里写调用 func 函数之前的逻辑'''
         res = func()
#         '''这里写调用 func 函数之后的逻辑'''
        return res
    return inner
 add = outer(func=add)
 add()

【六】带参装饰器模板

def outer(func):
    def inner(*args,**kwargs):
        '''这里写调用 func 函数之前的逻辑 '''
        res = func(*args,**kwargs)
        '''这里写调用 func 函数之后的逻辑'''
        return res
    return inner
@outer
def add(*args,**kwargs):
    print(args)
    print(kwargs)
user_data_dict = {'username': 'tony', 'age': 16}

def see(func):
    def inner(*args, **kwargs):
        if user_data_dict['age'] >= 18:
            res = func(*args, **kwargs)
            return res
        else:
            print(f'不能看电影')
    return inner

@see
def watch():
    print(f'可以看电影')

watch()

标签:return,dict,inner,func,装饰,def,user
From: https://www.cnblogs.com/banchengyanyu/p/17895103.html

相关文章

  • 装饰器
    今日习题*函数的四种定义方式*函数的调用方式*函数的参数类型*函数的形参类型都有哪些*函数实参传参都能如何传参*名称空间是什么,有哪些*作用域是什么,都有哪些*什么是闭包函数#【一】函数的四种定义方式#【1】无参无返回值的函数defindex():res=1+1prin......
  • NestJS 筑基:TypeScript 类和装饰器
    前言先回顾下前文中介绍了哪些内容:使用@nestjs/cli创建和管理Nest应用Hello,World示例代码分析Nest基本概念:模块,控制器,服务常用的装饰器:@Module、@Controller、@Get、@InjectableNest目录结构分析@nest/cli脚手架的命令本文先不继续讲解Nest中的内容,而是打算介绍TypeSc......
  • Python - 【装饰器】详解
    一.概念Python装饰器本质上是一个函数,用于修改其他函数的功能。装饰器可以在不改变函数代码的情况下添加新的功能,使代码更具可读性、可维护性和可重用性。使用装饰器可以把一个函数传递给另一个函数,使其具有新的行为,而无需修改函数本身的代码。二.基本语法@decorator_namedeff......
  • 【python】@property装饰器
    @property介绍:@property是一个内置的装饰器,用于将一个方法变成属性调用。让方法可以像实例属性那样进行访问,这样可以保证对象状态的封装性,同时,将数据的“获取”和“修改”集成到一处处理,提高代码的可读性和可维护性。通过对比,解释@property的意义:classPerson:def__init_......
  • Python装饰器
    一、核心思想在不改变被装饰对象内部代码和原有调用方式的基础之上在添加额外的功能二、装饰器的实现过程根据实际需要,一步一步满足需求,完成对装饰器的理解1、简易版本给index函数添加统计执行时间的功能importtimedefindex():time.sleep(3)print('fromind......
  • 深入探讨 Python 中的装饰器和上下文管理器
    Python作为一门灵活而强大的语言,提供了许多高级特性,其中装饰器(Decorators)和上下文管理器(ContextManagers)是其中两个非常有用的概念。这两个功能性特性提供了对代码结构和行为进行修改和控制的强大工具。它们允许程序员在不修改源代码的情况下,添加、修改或扩展函数或类的功能,帮助......
  • 01 装饰器的使用
    装饰器实现登录验证在一个web项目中,很多接口需要用户必须是登录状态,否则就应该跳转到登录页面,这个可以通过装饰器实现。在实现之前,我们必须弄清除两个问题装饰器执行先后的问题可以看到装饰器在函数被加载的时候就执行了,先执行的最下层的装饰器,再执行的上层的装饰器,这像什么......
  • python 属性装饰器和对应的setter方法,属性的封装和安全性控制
    当我们在类中定义属性时,通常希望能够对属性的读取和写入进行控制,以确保数据的完整性和安全性。属性装饰器和对应的setter方法提供了一种实现属性封装和安全性控制的方法。属性装饰器是Python的一种语法特性,用于修饰类的方法,使其表现为一个属性而不是一个普通的方法。通过使用属性......
  • Python中的装饰器
    一、装饰器的作用装饰器是Python中一种强大的编程工具,它允许我们在不修改原始函数代码的情况下,动态地增加功能或修改函数行为。装饰器提供了一种简洁而优雅的方式来修改、扩展或包装函数,使代码更具可读性和可维护性。装饰器的主要作用包括:添加额外的功能或逻辑,如日志记录、性......
  • python装饰器
    装饰器本质上是一个Python函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对象Python中的函数可以像普通变量一样当做参数传递给另外一个函数,也可以把一个函数作为返回值,这类函数被称为高阶(Higher-order)函数它经常......