Python的学习笔记--装饰器

付威     2019-03-14   1771   5min  

python的函数也属于一个对象,可以有一个变量来代替,例如前面说过的一个例子:

f=abs
print(f(-10))

如果我们在不改变原来函数的前提下,想扩展一个函数的功能。可以重新定义一个函数,把要原函数作为参数传递给增强函数,在调用函数前执行一些动作。

def revert(a):
    return abs(a)

def new_func(func):
     print("do something")
     return func

f=new_func(revert)
print(f(-10))

打印结果是:

do something
10

对于上面的代码,new_func就是装饰器,可以使用@对其进行简化:

def new_func(func):
     print("do something")
     return func
     
@new_func
def revert(a):
    return abs(a)

print(revert(-10))

这样可以省去一个变量的定义,也维持了原来的方法名称。

上面的装饰器有点过于简单,因为我们只能在return 语句前增加内容,想在方法后面增加一个确不行,为了能够实现更强大的装饰器,我们可以对其做修改,再增加一层函数:

def new_func(func):
    def inner(a):
        print("do something")
        res=func(a)
        print("something is done")
        return res
    return inner
     
@new_func
def revert(a):
    print ("processing")
    return abs(a)
 
print(revert(-10))

打印结果:

do something
processing
something is done
10

上面这个装饰器基本满足了我们的需求,但同样还有一个问题,上面的装饰器,只能传递一个参数,所以还是不够一般性。

我们可以使用函数的默认值的方法来解决这个问题,官方给的是*args 和 **kwargs(tuple和dict类型),修改如下:

def new_func(func):
    def inner(*args,**kw):
        print("do something")
        res=func(*args,**kw)
        print("something is done")
        return res
    return inner  
@new_func
def revert(a):
    print ("processing")
    return abs(a)

print(revert(-10))

我们再增加一个方法:

@new_func
def add(x,y):
    print ("processing")
    return x+y;
print(add(1,2))

打印结果是:

do something
processing
something is done
3

装饰器也可以传递参数,但是需要更深层次的函数:

def new_func(text):
    print ("call method:",text)
    def wapper(func):
        def inner(*args,**kw):
            print("do something")
            res=func(*args,**kw)
            print("something is done")
            return res
        return inner  
    return wapper

@new_func("revert")
def revert(a):
    print ("processing")
    return abs(a)
 
print(revert(-10))

运行结果:

call method: revert
do something
processing
something is done
10
(本文完)

作者:付威

博客地址:http://blog.laofu.online

如果觉得对您有帮助,可以下方的RSS订阅,谢谢合作

如有任何知识产权、版权问题或理论错误,还请指正。

本文是付威的网络博客原创,自由转载-非商用-非衍生-保持署名,请遵循:创意共享3.0许可证

交流请加群113249828: 点击加群   或发我邮件 laofu_online@163.com

付威

获得最新的博主文章,请关注上方公众号