python装饰器及warp的作用

很久以前就有看过装饰器的用法和功能,但是自己平时在编程的时候基本上很少用到这些高级的用法。今天看别人开源的efficientDet的源码时,很多地方用了装饰器,一时想不起来具体作用了,所以又百度学习了一波。现在以我个人理解总结下,以便日后忘记可以在复习下。

首先装饰器是python一个很强大的功能,也是动态编程的一个特点。

首先我们知道,在python中一个函数可以作为参数传给另外一个函数:

def hi():
    return "hi yasoob!"
 
def doSomethingBeforeHi(func):
    print("I am doing some boring work before executing hi()")
    print(func())
 
doSomethingBeforeHi(hi)

#outputs:I am doing some boring work before executing hi()
#        hi yasoob!

下面装饰器的用法,就是“装饰一个函数”让这个被装饰的函数作为装饰器的参数进行调用:


import functools
 
def itcast1(fun):
 
    # 带参数的装饰器
 
    def inner(*args, **kwargs):
 
        print("itcast1 start")
 
        fun(*args, **kwargs)
 
        print("itcast1 end")
    return inner


@itcast1
def say_hello():
    print('say_hello')
 
print(say_hello.__name__)
say_hello
 

>> output:  inner
            itcast1 start
            say_hello
            itcast1 end

可以看到,被装饰之后的函数,就不是函数本身了,名字变成了装饰器的返回函数,并且是直接调用inner函数,所以输出调用的顺序就如inner里面的顺序。这样做可以大大简化我们的代码,将装饰器的功能写好,直接装饰给其他函数就可以了。

接下来看看warp,它作用主要是保持原有函数的名字,doc的属性。

import functools
def itcast1(fun):
    @functools.wraps(fun)
    def inner(*args, **kwargs):
        print('itcast1 start')
        a=fun(*args, **kwargs)
        print("itcast1 end")
        
    return inner

@itcast1
def say_hello(a):
    print('say_hello')
    print(a)
    return a

print(say_hello.__name__)

say_hello()

>>output:
say_hello
itcast1 start
say_hello
itcast1 end

从输出可以看出,函数的名字没变还是原有函数,而同时继承了装饰器内的功能。

如果我们被装饰的函数有返回值,我们想得到这个返回值,只需要在inner里返回就可以了。如下:

import functools
def itcast1(fun):
    @functools.wraps(fun)
    def inner(*args, **kwargs):
        print('itcast1 start')
        a=fun(*args, **kwargs)
        print("itcast1 end")
        return a
    return inner

@itcast1
def say_hello(a):
    print('say_hello')
    print(a)
    return a

print(say_hello.__name__)

a=say_hello(1)
print(a)

>>output:
say_hello
itcast1 start
say_hello
1
itcast1 end
1

关于的使用@property ,主要作用可以把类中的函数作为类的属性调用

详细看这个:https://www.liaoxuefeng.com/wiki/897692888725344/923030547069856

猜你喜欢

转载自blog.csdn.net/qq_26593695/article/details/103802342