python装饰器

python装饰器的操作

  • 函数重名

    def test1():
        print('----1----')
    
    def test1():
        print('----2----')
    
    test1()  #这里打印 ----2---- 因为test1现在指向了下面这个函数
    
    # 运行结果
    ----2----
    
  • 装饰器-1

    '''
                     装饰器
    
    装饰器是程序开发中经常用到的一个功能,用好了装饰器,
    
    开发效率如虎添翼,所以这也是Python面试中必问的问题,
    
    但对于好多初次接触这个知识的人来讲,这个功能有点绕,
    
    自学时直接绕过去,然后面试问道了就挂了,因为装饰器是
    
    程序开发的基础知识,这个都不会,别跟人家说你会Python
    
    看下面的文章,保证你学会装饰器.
    
    
    1.先明白这段代码
    
    ###第一波###
    
    def foo():
        print('foo')
    
    foo     #表示是函数
    foo()   #表示执行函数
    
    ###第二波###
    
    def foo():
        print('foo')
    
    foo = lambda x :x + 1
    
    foo() #执行下面的lambda表达式,而不在是原来的foo函数,因为foo这个名字被重新指向了另外一个匿名数
    
    '''
    
    def w1(func):
        def inner():
            print('----正在验证----')
            func()
        return inner
    
    def f1():
        print('----f1----')
    
    def f2():
        print('----f2----')
    
    #innerFunc = w1(f1) #这里跟下面的意思一样
    
    #innerFunc()
    f1 = w1(f1) #把f1传递给func func指向了f1原来的那个函数 w1反回inner这个函数的引用 f1指向了这个引用
    
    f1() #f1指向了inner这个函数的地址 f1()现在调用的就是inner这个函数
    
    # 运行结果
    ----正在验证----
    ----f1----
    
  • 装饰器-2

    def w1(func):
        def inner():
            print('----正在验证----')
            if True:
                func()
            else:
                print("没有权限")
        return inner
    
    @w1  #这里的@w1 <==> f1 = w1(f1)
    def f1():
        print('----f1----')
    
    @w1
    def f2():
        print('----f2----')
    
    
    #f1 = w1(f1) #把f1传递给func func指向了f1原来的那个函数 w1反回inner这个函数的引用 f1指向了这个引用
    
    #f1() #f1指向了inner这个函数的地址 f1()现在调用的就是inner这个函数
    
    f1()
    f2()
    
    # 运行结果
    ----正在验证----
    ----f1----
    ----正在验证----
    ----f2----
    
  • 多个装饰器

    #定义函数:完成包裹数据
    def makeBold(fn):
        def wrapped():
            print('----1----')
            return ""+fn()+""
        return wrapped
    
    
    #定义函数:完成包裹数据
    def makeItalic(fn):
        def wrapped():
            print("----2----")
            return ""+fn()+""
        return wrapped
    
    @makeBold #@makeBold <====> test3 = makeBold(test3)   在封装这个  因为它下面没有函数调用
    @makeItalic #@makeItalic <===> test3 = makeItalic(test3)  先封装这个
    def test3():#这个画图就知道了
        print("----3----")
        return "hello world-3"
    
    result = test3()
    print(result)
    
    # 运行结果
    ----1----
    ----2----
    ----3----
    <b><i>hello world-3</i></b>
    
  • 装饰器什么时候进行装饰

    def w1(func):
        def inner():
            print('----正在验证----')
            func()
        return inner
    
    #只要python解释器执行到了这个代码(@w1),那么就会自动的进行装饰,而不是等到调用的时候才装饰的
    @w1     # @w1 <==> f1=w1(f1)
    def f1():
        print('----f1----')
    
    #在调用f1之前,已经进行装饰了
    f1() 
    
    # 运行结果
    ----正在验证----
    ----f1----
    
  • 多个装饰器-2

    def w1(func):
        print("----正在验证1----")
        def inner():
            print("----正在获取权限1----")
            func()
        return inner
    
    def w2(func):
        print("----正在验证2----")
        def inner():
            print("----正在获取权限2----")
            func()
        return inner
    
    
    # 只要python解释器执行到了这个代码,那么就会自动的进行装饰,而不是等到调用的时候才装饰
    @w1
    @w2     #装饰是从下往上,调用是从上往下  执行结果为 ----正在验证2----,--正在1---,---获取1--,---获取2---,---f1---
    def f1():
        print("----f1----")
    
    #在调用f1之前,已经进行装饰了
    f1()
    
    # 运行结果
    ----正在验证2----
    ----正在验证1----
    ----正在获取权限1----
    ----正在获取权限2----
    ----f1----
    
  • 使用装饰器对无参数的函数进行装饰

    def func(functionName):
        print("----func----1----")
        def func_in():
            print("----func_in----1----")
            functionName()
            print("----func_in----2----")
    
        print("----func----2----")
        return func_in
    
    @func
    def test():
        print("----test----")
    
    #test = func(test)
    
    test()
    
    # 运行结果
    ----func----1----
    ----func----2----
    ----func_in----1----
    ----test----
    ----func_in----2----
    
  • 使用装饰器对有参数的函数进行装饰

    def func(functionName):
        print("----func----1----")
        def func_in(a,b): #如果a,b 没有定义,那么导致17行的调用个失败
            print("----func_in----1----")
            functionName(a,b) #如果a,b 没有当做实参传递,那么会导致调用12行的的函数失败
            print("----func_in----2----")
    
        print("----func----2----")
        return func_in
    
    @func
    def test(a,b):
        print("----test-a=%d-b=%d--"%(a,b))
    
    #test = func(test)
    
    test(11,22)
    
    # 运行结果
    ----func----1----
    ----func----2----
    ----func_in----1----
    ----test-a=11-b=22--
    ----func_in----2----
    
  • 使用装饰器对不定长参数的函数进行装饰

    def func(functionName):
        print("----func----1----")
        def func_in(*args,**kwargs): #如果*args,**kwargs 没有定义,那么导致19,21行的调用个失败
            print("----func_in----1----")
            functionName(*args,**kwargs) #如果args,kwargs会报错,因为没有解包  *args,**kwargs这是解包
            print("----func_in----2----")#没有当做实参传递,那么会导致调用12,16行的的函数失败
    
        print("----func----2----")
        return func_in
    
    @func
    def test(a,b,c):
        print("----test-a=%d-b=%d-c=%d-"%(a,b,c))
    
    @func
    def test2(a,b,c,d):
        print("----test-a=%d-b=%d-c=%d-d=%d"%(a,b,c,d))
    
    test(11,22,33)
    
    test2(44,55,66,77)
    
    # 运行结果
    ----func----1----
    ----func----2----
    ----func----1----
    ----func----2----
    ----func_in----1----
    ----test-a=11-b=22-c=33-
    ----func_in----2----
    ----func_in----1----
    ----test-a=44-b=55-c=66-d=77
    ----func_in----2----
    
  • 使用装饰器对有返回值的函数进行装饰

    def func(functionName):
        print("----func----1----")
        def func_in():
            print("----func_in----1----")
            ret = functionName() #保存反回来的haha
            print("----func_in----2----")
            return ret #把haha反回到16行的调用
        print("----func----2----")
        return func_in
    
    @func
    def test():
        print("----test----")
        return "haha"
    
    ret = test()
    print("test return value is %s"%(ret))
    
    # 运行结果
    ----func----1----
    ----func----2----
    ----func_in----1----
    ----test----
    ----func_in----2----
    test return value is haha
    
  • 使用通用装饰器完成对函数进行装饰

    def func(functionName):
        def func_in(*args,**kwargs):
            print("----正在记录中----")
            ret = functionName(*args,**kwargs)
            return ret
        return func_in
    
    @func
    def test():
        print("----test----")
        return "haha"
    
    @func
    def test2():
        print("----test2----")
    
    @func
    def test3(a,b):
        print("----test3-a=%d-b=%d----"%(a,b))
    
    
    ret = test()
    print("test return value is %s"%(ret))
    
    ret = test2()
    print("test return value is %s"%(ret))
    
    test3(11,22)
    
    # 运行结果
    ----正在记录中----
    ----test----
    test return value is haha
    ----正在记录中----
    ----test2----
    test return value is None
    ----正在记录中----
    ----test3-a=11-b=22----
    
  • 带有参数的装饰器

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

你可能感兴趣的:(python高级)