Python mini-web框架3:装饰器

简介: Python mini-web框架3:装饰器

一、看一个例子,来引出装饰器



需求:在不改变下面 test() 函数的情况下,执行函数的情况下先进行其他的步骤,看下面的实现

def set_func(func):
    print("----开始装饰----")
    def run_func():
        print("----验证权限1----")
        func()
    return run_func
def test1():
    print("----test----")
test1 = set_func(test1)
test1()

执行结果是:

----开始装饰----
----验证权限1----
----test----


image.png

  • 分析:test1 = set_fun(test1) 改变了 test1() 的指向,指向了闭包内的run_func()函数,在test()执行的时候,执行的是run_func()函数内的代码
  • 优化: 不想写 test1 = set_fun(test1) 这句代码,我们可以在 def test1():上面写 @set_fun,我们在下面具体看使用。


二、装饰器的介绍以及参数



  • 2.1、简单的来说:一个闭包对一个函数进行装饰就组成了装饰器,如下的例子,@set_fun是一种 语法糖


def set_func(func):
     print("----开始装饰----")
     def run_func():
         print("----验证权限1----")
         func()
     return run_func
@set_func    # @set_fun 与 test1 = set_func(test1) 等价
def test1():
    print("----test----")
test1()

提示:  @set_fun 与 test1 = set_fun(test1)  等价


  • 2.2、装饰器对有 单个参数 函数的装饰(说白了就是传参)


def set_func(func):
     print("----开始装饰----")
     def run_func(num):
          print("----验证权限1----")
          func(num)
     return run_func
@set_func
def test1(num):
     print("----test----%d"%num)
test1(3)

提示:test1指向的是闭包内的run_func函数,传的参数也是给run_func,函数内再调用test1函数,不要绕,好好理解下


  • 2.3、不定长参数的函数装饰(说白了就是参数不定),如下例子


def set_func(func):
    print("----开始装饰----")
    def run_func(*args,**kwargs):
        print("----验证权限1----")
        func(*args,**kwargs)
    return run_func
@set_func
def test1(num,*args,**kwargs):
    print("----test----%d"%num,args,kwargs)
test1(3,2,1,a="1")
  • 打印结果是:


----开始装饰----
----验证权限1----
----test----3 (2, 1) {'a': '1'}


注意:

  • 闭包 里面的 func(*args,**kwargs) 中的 *args**kwargs是解包的意思,传参不能直接传元组与字典,要解包
  • 不可以传 func(args,kwargs),必挂,这样是传了两个参数,一个元组,一个字典,是不对的


  • 2.4、对应有返回值函数进行装饰、通用装饰器


def set_func(func):
      print("----开始装饰----")
      def run_func(*args,**kwargs):
            print("----验证权限1----")
            return func(*args,**kwargs) # 拆包
      return run_func
@set_func
def test1(num,*args,**kwargs):
      print("----test----%d"%num,args,kwargs)
      return "OK"
@set_func
def test2():
      return "OK2"
test1(3,2,1,a="1")
print(test2())
  • 打印结果是:


----开始装饰----
----开始装饰----
----验证权限1----
----test----3 (2, 1) {'a': '1'}
----验证权限1----
OK2


image.png

image.png


  • 2.5、多个装饰器对同一个函数进行装饰


def set_func1(func):
     print("----开始装饰1----")
     def run_func1(*args,**kwargs):
         print("----验证权限1----")
         func(*args,**kwargs) # 拆包
     return run_func1
def set_func2(func):
     print("----开始装饰2----")
     def run_func2(*args,**kwargs):
         print("----验证权限2----")
         func(*args,**kwargs) # 拆包
     return run_func2
@set_func1
@set_func2
def test1(num,*args,**kwargs):
      print("----test----%d"%num,args,kwargs)
test1(3,2,1,a="1")
  • 打印结果:


----开始装饰2----
----开始装饰1----
----验证权限1----
----验证权限2----
----test----3 (2, 1) {'a': '1'}

提示:当多个装饰器装饰同一个函数的时候,装饰从下往上装饰,也就是上面例子中先装饰  set_func2,再装饰set_func1

装饰器在调用之前就已经装好了,组成一个大的闭包空间;执行的时候,先执行后装饰的装饰器里面的代码,后执行前一个被装饰的代码,依次类推,最后执行第一个装饰的闭包内的代码。


  • 2.6、对于同一个装饰器,对多个函数进行装饰
    分析:对于同一个装饰器,对多个函数进行装饰的时候,在没调用之前就会进行装饰,每装饰一个就生成一个闭包。闭包内外部函数的变量指向原函数


def set_func(func):
      print("----开始装饰----")
      def run_func(*args,**kwargs):
             print("----验证权限----")
             func(*args,**kwargs) # 拆包
      return run_func
@set_func
def test1(num,*args,**kwargs):
      print("----test1----%d"%num,args,kwargs)
@set_func
def test2(num,*args,**kwargs):
      print("----test2----%d"%num,args,kwargs)
test1(3,2,1,a="1")
test2(4,5,6,a="2")
  • 打印结果:


----开始装饰----
----开始装饰----
----验证权限----
----test1----3 (2, 1) {'a': '1'}
----验证权限----
----test2----4 (5, 6) {'a': '2'}
  • 2.7、用类对函数进行装饰


class Test(object):
    """docstring for ClassName"""
    def __init__(self, func):
        self.func = func
    def __call__(self):
        print("这里是装饰器添加的功能")
        return self.func()
@Test  # 相当于 get_str = Test(get_str)
def get_str():
     return "测试"
print(get_str())
  • 打印结果:


这里是装饰器添加的功能
测试


三、带有参数的装饰器,是装饰器加参数,如下


def set_level(level):
    def set_func(func):
        def call_func(*args,**kwargs):
           if level ==1 :
                print("权限验证-- %d"%level)
           elif level ==2 :
                print("权限验证-- %d"%level)
           else:
                print("权限验证-- %d"%level)
           func(*args,**kwargs)
        return call_func
    return set_func
@set_level(9)
def test1():
    print("------test1------")
test1()


  • 分析:上面就是给装饰器加参数set_level(9):
  • 1、调用set_level并且将9当做实参传递
  • 2、用上一步调用的返回值当做装饰器对test1函数进行装饰


总结:不要觉得装饰器很难,其实它就是:函数的指向的改变,以闭包为例,闭包作为另一个函数的装饰器,装饰后,在闭包的内部函数再去调用函数,其实就是在函数执行之前先调用闭包内的代码。

目录
相关文章
|
15天前
|
Python
深入理解Python装饰器:从入门到实践####
本文旨在通过简明扼要的方式,为读者揭开Python装饰器的神秘面纱,从基本概念、工作原理到实际应用场景进行全面解析。不同于常规的摘要仅概述内容概要,本文将直接以一段精炼代码示例开篇,展示装饰器如何优雅地增强函数功能,激发读者探索兴趣,随后深入探讨其背后的机制与高级用法。 ####
46 11
|
11天前
|
设计模式 缓存 开发者
深入浅出Python装饰器
【10月更文挑战第39天】本文将通过浅显易懂的语言和生动的比喻,带你探索Python中一个神奇而又强大的特性——装饰器。我们将一起揭开装饰器的神秘面纱,了解它的工作原理,并通过实际代码示例学习如何应用它来美化我们的代码。无论你是编程新手还是有经验的开发者,这篇文章都将为你打开一扇新的大门,让你的代码更加优雅和高效。
|
11天前
|
缓存 测试技术 数据库
深入理解Python中的装饰器
在本文中,我们将探讨Python语言中一个强大而灵活的特性——装饰器。装饰器允许开发者在不修改原有函数或方法代码的情况下增加额外的功能,这大大提高了代码的复用性和可读性。通过具体示例和应用场景的讲解,本篇文章旨在为读者提供一个关于如何使用装饰器的全面指南,包括装饰器的定义、使用场景、以及如何自定义装饰器等内容。
|
6天前
|
JSON 前端开发 API
使用Python和Flask构建简易Web API
使用Python和Flask构建简易Web API
|
6天前
|
缓存 API 数据库
Python哪个框架合适开发速卖通商品详情api?
在跨境电商平台速卖通的商品详情数据获取与整合中,Python 语言及其多种框架(如 Flask、Django、Tornado 和 FastAPI)提供了高效解决方案。Flask 简洁灵活,适合快速开发;Django 功能全面,适用于大型项目;Tornado 性能卓越,擅长处理高并发;FastAPI 结合类型提示和异步编程,开发体验优秀。选择合适的框架需综合考虑项目规模、性能要求和团队技术栈。
18 2
|
6天前
|
开发框架 缓存 测试技术
Python中的装饰器:魔法般的功能增强
在Python编程中,装饰器是一种强大而灵活的工具,它允许开发者修改或扩展函数和类的行为。本文将深入探讨Python装饰器的工作原理,并通过实例演示如何创建和使用自定义装饰器来增强代码的功能性和可读性。我们将从基础概念讲起,逐步深入到高级应用,揭示装饰器背后的“魔法”,并展示它们在实际开发中的多种用途。
|
11天前
|
关系型数据库 数据库 数据安全/隐私保护
Python Web开发
Python Web开发
40 6
|
12天前
|
缓存 监控 测试技术
Python中的装饰器:功能扩展与代码复用的利器###
本文深入探讨了Python中装饰器的概念、实现机制及其在实际开发中的应用价值。通过生动的实例和详尽的解释,文章展示了装饰器如何增强函数功能、提升代码可读性和维护性,并鼓励读者在项目中灵活运用这一强大的语言特性。 ###
|
11天前
|
设计模式 缓存 开发框架
Python中的装饰器:从入门到实践####
本文深入探讨了Python中装饰器的工作原理与应用,通过具体案例展示了如何利用装饰器增强函数功能、提高代码复用性和可读性。读者将学习到装饰器的基本概念、实现方法及其在实际项目开发中的实用技巧。 ####
22 3
|
11天前
|
Python
探索Python中的装饰器:简化代码,提升效率
【10月更文挑战第39天】在编程的世界中,我们总是在寻找使代码更简洁、更高效的方法。Python的装饰器提供了一种强大的工具,能够让我们做到这一点。本文将深入探讨装饰器的基本概念,展示如何通过它们来增强函数的功能,同时保持代码的整洁性。我们将从基础开始,逐步深入到装饰器的高级用法,让你了解如何利用这一特性来优化你的Python代码。准备好让你的代码变得更加优雅和强大了吗?让我们开始吧!
19 1
下一篇
无影云桌面