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函数进行装饰


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

目录
相关文章
|
1天前
|
数据采集 Web App开发 存储
打造高效的Web Scraper:Python与Selenium的完美结合
本文介绍如何使用Python结合Selenium,通过代理IP、设置Cookie和User-Agent抓取BOSS直聘的招聘信息,包括公司名称、岗位、要求和薪资。这些数据可用于行业趋势、人才需求、企业动态及区域经济分析,为求职者、企业和分析师提供宝贵信息。文中详细说明了环境准备、代理配置、登录操作及数据抓取步骤,并提醒注意反爬虫机制和验证码处理等问题。
打造高效的Web Scraper:Python与Selenium的完美结合
|
22天前
|
人工智能 开发者 Python
Chainlit:一个开源的异步Python框架,快速构建生产级对话式 AI 应用
Chainlit 是一个开源的异步 Python 框架,帮助开发者在几分钟内构建可扩展的对话式 AI 或代理应用,支持多种工具和服务集成。
137 9
|
1月前
|
设计模式 前端开发 Shell
Python装饰器是什么?
装饰器是Python中用于动态修改函数、方法或类功能的工具,无需改变原代码。通过将函数作为参数传递并返回新函数,装饰器可以在原函数执行前后添加额外逻辑。例如,使用`@logger`装饰器可以打印函数调用日志,而`@timethis`则可用于计算函数执行时间。为了保持被装饰函数的元信息(如`__name__`和`__doc__`),可使用`functools.wraps`装饰器。此外,带参数的装饰器可通过嵌套函数实现,如`@timeitS(2)`,以根据参数条件输出特定信息。
90 59
|
1月前
|
测试技术 数据库 Python
Python装饰器实战:打造高效性能计时工具
在数据分析中,处理大规模数据时,分析代码性能至关重要。本文介绍如何使用Python装饰器实现性能计时工具,在不改变现有代码的基础上,方便快速地测试函数执行时间。该方法具有侵入性小、复用性强、灵活度高等优点,有助于快速发现性能瓶颈并优化代码。通过设置循环次数参数,可以更准确地评估函数的平均执行时间,提升开发效率。
106 61
Python装饰器实战:打造高效性能计时工具
|
1月前
|
关系型数据库 API 数据库
Python流行orm框架对比
Python中有多个流行的ORM框架,如SQLAlchemy、Django ORM、Peewee、Tortoise ORM、Pony ORM、SQLModel和GINO。每个框架各有特点,适用于不同的项目需求。SQLAlchemy功能强大且灵活,适合复杂项目;Django ORM与Django框架无缝集成,易用性强;Peewee轻量级且简单,适合小型项目;Tortoise ORM专为异步框架设计;Pony ORM查询语法直观;SQLModel结合Pydantic,适合FastAPI;GINO则适合异步环境开发。初学者推荐使用Django ORM或Peewee,因其易学易用。
|
1月前
|
人工智能 分布式计算 大数据
MaxFrame 产品评测:大数据与AI融合的Python分布式计算框架
MaxFrame是阿里云MaxCompute推出的自研Python分布式计算框架,支持大规模数据处理与AI应用。它提供类似Pandas的API,简化开发流程,并兼容多种机器学习库,加速模型训练前的数据准备。MaxFrame融合大数据和AI,提升效率、促进协作、增强创新能力。尽管初次配置稍显复杂,但其强大的功能集、性能优化及开放性使其成为现代企业与研究机构的理想选择。未来有望进一步简化使用门槛并加强社区建设。
80 7
|
1月前
|
JSON 安全 中间件
Python Web 框架 FastAPI
FastAPI 是一个现代的 Python Web 框架,专为快速构建 API 和在线应用而设计。它凭借速度、简单性和开发人员友好的特性迅速走红。FastAPI 支持自动文档生成、类型提示、数据验证、异步操作和依赖注入等功能,极大提升了开发效率并减少了错误。安装简单,使用 pip 安装 FastAPI 和 uvicorn 即可开始开发。其优点包括高性能、自动数据验证和身份验证支持,但也存在学习曲线和社区资源相对较少的缺点。
84 15
|
1月前
|
安全 前端开发 数据库
Python 语言结合 Flask 框架来实现一个基础的代购商品管理、用户下单等功能的简易系统
这是一个使用 Python 和 Flask 框架实现的简易代购系统示例,涵盖商品管理、用户注册登录、订单创建及查看等功能。通过 SQLAlchemy 进行数据库操作,支持添加商品、展示详情、库存管理等。用户可注册登录并下单,系统会检查库存并记录订单。此代码仅为参考,实际应用需进一步完善,如增强安全性、集成支付接口、优化界面等。
|
2月前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
116 2
|
2月前
|
JSON 数据可视化 测试技术
python+requests接口自动化框架的实现
通过以上步骤,我们构建了一个基本的Python+Requests接口自动化测试框架。这个框架具有良好的扩展性,可以根据实际需求进行功能扩展和优化。它不仅能提高测试效率,还能保证接口的稳定性和可靠性,为软件质量提供有力保障。
96 7

热门文章

最新文章

推荐镜像

更多