• 10 带参数的装饰器 通用装饰器 类装饰器


    版本1)不带参数的闭包

    def timefun(func):
        print('---fun1--')    
        def time_in():
            print("--time_in is 1")
            func()
            print('---time_in is 2')
    
        print('---fun2--')    
        return time_in
    
    def f1():
        print("this is f1")
    
    f1 = timefun(f1)
    
    f1()
    ---fun1--
    ---fun2--
    --time_in is 1
    this is f1
    ---time_in is 2

    版本2)不带参数函数的被装饰

    def timefun(func):
        print('---fun1--')    
        def time_in():
            print("--time_in is 1")
            func()
            print('---time_in is 2')
    
        print('---fun2--')    
        return time_in
    
    @timefun
    def f1():
        print("this is f1")
    
    f1()

    版本3)带参数函数的被装饰

    def timefun(func):
        print('---fun1--')    
        def time_in(num1,num2):
            print("--time_in is 1")
            func(num1,num2)
            print('---time_in is 2')
    
        print('---fun2--')    
        return time_in
    
    @timefun
    def f1(a,b):
        print('--f1:a=%d,b=%d'%(a,b))
    
    f1(1,2)

    版本4)不定长参数函数被装饰

    def timefun(func):
        print('---装饰用的1--')    
        def time_in(*args,**kwargs):
            print("--time_in is 1")
            func(*args,**kwargs)
            print('---time_in is 2')
    
        print('---fun2--')    
        return time_in
    
    @timefun
    def f1(a,b):
        print('--f1:a=%d,b=%d'%(a,b))
    
    @timefun
    def f2(a,b,c,d):
        print('--f2:a=%d,b=%d,c=%d,d=%d'%(a,b,c,d))
    
    f1(1,2)
    f2(1,2,3,4)

    5  带返回值的函数 被装饰

      1)带返回值的函数

     
     def test():
         print('----test--')
         return "haha"
     
     ret = test()
     print("test return ---%s"%ret)
    
    
    
    ## 运行结果
    ----test--
    test return ---haha

      

      2)带返回值的装饰器

    def fun(func):
        
        def time_in():
            func()
        return time_in
    
    @fun
    def test():
        print('----test--')
        return "haha"
    
    ret = test()
    print("test return ---%s"%ret)
    
    
    ### 运行结果
    ----test--
    test return ---None

      

      3)带返回值的函数 被装饰

    def fun(func):
        
        def time_in():
            ret = func()  #保存返回来的haha
            return ret   #把haha返回到最后17行的调用
        return time_in 
    
    @fun
    def test():
        print('----test--')
        return "haha"
    
    ret = test()
    print("test return ---%s"%ret)

    6.通用装饰器

    def func(func):
    
        def fun_in(*args,**kwargs):
            print('--记录日志--')
            re = func(*args,**kwargs)
            return re
        return fun_in
    
    @func
    def test1():
        print('--test1')
        return "haha"
    
    @func
    def test2():
        print('--test2--a=%d')
        
    @func
    def test3(a):
        print('--test3--a=%d'%a)
    
    ret = test1()
    print('test return :%s'%ret)
    
    ret2 = test2()
    print('test2 return :%s'%ret2)
    
    test3(11)
    --记录日志--
    --test1
    test return :haha
    --记录日志--
    --test2--a=%d
    test2 return :None
    --记录日志--
    --test3--a=11

    7.装饰器带参数,

    在原有装饰器的基础上,设置外部变量,执行一次函数,获取它的返回值而已

    def func_arg(arg):
        def func(functionName):
            
            def func_in():
                print("---记录日志-%s-"%arg)
                functionName()
            return func_in
        return func
    #1.先执行func_arg("heihei")函数,这个函数return 的结果是func这个函数的引用
    #2.@func
    #3.使用@func对test进行装饰
    @func_arg('heihei')
    def test1():
        print('---testt')
    
    test1()
    ---记录日志-heihei-
    ---testt

    2)有什么用

    def func_arg(arg):
        def func(functionName):
            
            def func_in():
                print("---记录日志-%s-"%arg)
                if arg == "alex":
                    functionName()
                    functionName()
                else:
                    functionName()
            return func_in
        return func
    #1.先执行func_arg("heihei")函数,这个函数return 的结果是func这个函数的引用
    #2.@func
    #3.使用@func对test进行装饰
    @func_arg('heihei')
    def test1():
        print('---testt')
    
    #带有参数的装饰器,能够起到在运行时,有不同的功能
    @func_arg('alex')
    def test2():
        print('---alex')
    
    test1()
    test2()
    ---记录日志-heihei-
    ---testt
    ---记录日志-alex-
    ---alex
    ---alex

    8.类装饰器__call__

      1 __call__方法

    装饰器函数其实是这样一个接口约束,它必须接受一个callable对象作为参数,然后返回一个callable对象。在Python中一般callable对象都是函数,但也有例外。只要某个对象重写了 __call__() 方法,那么这个对象就是callable的。

    In [18]: class Dog(object):
       ....:     def __call__(self):
       ....:         print("---test-")
       ....:         
    
    In [19]: d = Dog()
    
    In [20]: d()
    ---test-

      2)类装饰器

    class Test(object):
        def __init__(self, func):
            print("---初始化---")
            print("func name is %s"%func.__name__)
            self.__func = func
        def __call__(self):
            print("---装饰器中的功能---")
            self.__func()
    #说明:
    #1. 当用Test来装作装饰器对test函数进行装饰的时候,首先会创建Test的实例对象
    #    并且会把test这个函数名当做参数传递到__init__方法中
    #    即在__init__方法中的func变量指向了test函数体
    #
    #2. test函数相当于指向了用Test创建出来的实例对象
    #
    #3. 当在使用test()进行调用时,就相当于让这个对象(),因此会调用这个对象的__call__方法
    #
    #4. 为了能够在__call__方法中调用原来test指向的函数体,所以在__init__方法中就需要一个实例属性来保存这个函数体的引用
    #    所以才有了self.__func = func这句代码,从而在调用__call__方法中能够调用到test之前的函数体
    @Test
    def test():
        print("----test---")
    test()
    showpy()#如果把这句话注释,重新运行程序,依然会看到"--初始化--"
    运行结果如下:
    
    ---初始化---
    func name is test
    ---装饰器中的功能---
    ----test---

        

        

  • 相关阅读:
    业余草双因素认证(2FA)教程
    业余草网站热门关键字
    微博爬虫“免登录”技巧详解及 Java 实现(业余草的博客)
    业余草通告CSDN博客用户zhang__ao非法转载文章的公告
    CODE大全给你推荐几个免费的leapftp 注册码
    业余草最新热门博客推荐
    莫比乌斯反演
    P5091 【模板】欧拉定理
    LaTeX Test
    P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
  • 原文地址:https://www.cnblogs.com/venicid/p/7929427.html
Copyright © 2020-2023  润新知