zoukankan      html  css  js  c++  java
  • 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---

        

        

  • 相关阅读:
    Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
    Combine 框架,从0到1 —— 4.在 Combine 中使用通知
    Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
    Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
    使用 Swift Package Manager 集成依赖库
    iOS 高效灵活地配置可复用视图组件的主题
    构建个人博客网站(基于Python Flask)
    Swift dynamic关键字
    Swift @objcMembers
    仅用递归函数操作逆序一个栈(Swift 4)
  • 原文地址:https://www.cnblogs.com/venicid/p/7929427.html
Copyright © 2011-2022 走看看