zoukankan      html  css  js  c++  java
  • Python学习:11.Python装饰器讲解(二)

    回顾

      上一节我们进行了Python简单装饰器的讲解,但是python的装饰器还有一部分高级的使用方式,这一节就针对python装饰器高级部分进行讲解。

    为一个函数添加多个装饰器

      今天,老板又交给你一个任务,老板说:"之前的装饰器用用起来挺好,但是这次我需要再次添加更多的参数,这个任务就交给你了,好好干。",这种时候,我们就可以针对一个函数使用多个装饰器。

    import datetime
    
    def hel(func):
        def inner(*args,**kwargs):
            r = func(*args,**kwargs)
            print('bye')
            return r
        return inner
    
    def hel1(func):
        def inner(*args,**kwargs):
            print('start time:%s' % datetime.datetime.now())
            r = func(*args,**kwargs)
            print('end time:%s'%datetime.datetime.now())
            return  r
        return  inner
    
    @hel1
    @hel
    def f1(name):
        print('hello')
        print(name)
    
    name = 'alexsel'
    f1(name)
    
    执行结果:
    start time:2018-07-01 10:36:02.085027
    hello
    alexsel
    bye
    end time:2018-07-01 10:36:02.086027

    这次我们在对之前代码添加数据的时候,我们写了第二个装饰器,我们使用这个装饰器针对之前的函数再次增加新的功能,输出了开始结束时间。

    代码及输出问题解析

    针对刚才多个装饰器,我们需要了解的是在进行输出的时候是怎么进行输出的,首先装饰器函数hel首先对f1函数进行装饰,然后装饰器函数hel1在对被hel装饰过函数进行装饰,最后执行两次装饰过的函数。在新添加的装饰器中(hel1)的func所指的函数是已经被hel装饰过的函数。

    带参数的装饰器

      装饰器在调用的时候可以传入相应的参数,传入参数以后我们可以根据不同的参数,针对函数进行相应信息输出。

    def use_log(level):
        def hel(func):
            def inner(*args,**kwargs):
                if level == 'warning':
                    print('The current function:%s'%func.__name__)
                r = func(*args,**kwargs)
                return r
            return inner
        return hel
    
    @use_log(level = 'warning')
    def f1(name):
        print('hello')
        print(name)
    
    
    f1(name = 'alexsel')
    
    输出结果:
    The current function:f1
    hello
    alexsel

    上面的代码就是可以带有参数的装饰器,就是将以前我们使用简单的装饰器进行了一次封装,当我们调用函数的时候,python可以将我们定义的装饰器的参数传入函数中。

    基于类的装饰器

      讲解python的类装饰器需要用到python类的知识,python的类我们还没有进行学习,就先简单了解一下。

      根据我们刚才对装饰器的学习,我们发现装饰器如果需要正常运行,装饰器所接受的对象必须是可调用的,然后在装饰器内部在返回一个可调用的对象,一般情况下,可调用的对象都是函数,特殊情况是对象中写入了__call__()方法就也是可以调用的对象。

    class Test():
        def __call__(self):
            print('test')
    
    te = Test()
    te()
    
    输出结果:
    test

    我们是有类装饰器的时候,可以让类的构造函数__init__()接受一个函数,然后重载一个__call__()并且返回一个函数,来达到装饰器的目的。

    class Test():
        def __init__(self,func):
            self.func = func
    
        def __call__(self,*args,**kwargs):
            print('The current function:%s' % self.func.__name__)
            return  self.func()
    
    @Test
    def tes():
        print('obj')
    
    tes()
    
    
    输出结果:
    The current function:tes
    tes

    装饰器就是对原来函数、对象功能的扩展,相当于对函数重新封装,重点需要理解的是装饰器中返回的是函数,而且装饰器所装饰器的对象也需要是可调用的。今天装饰器的高级部分就到这里。

  • 相关阅读:
    day07_final
    day06_final
    day02_final
    day04_final
    New
    AtCoder Grand Contest 015 E Mr.Aoki Incubator
    长链剖分学习笔记
    关于某些莫队的优化
    CodePlus 2019 3月月赛 Div.1 A题 TREE
    边分治学习笔记
  • 原文地址:https://www.cnblogs.com/liudi2017/p/9251971.html
Copyright © 2011-2022 走看看