当需要对已定义的函数进行功能扩展但又不能去改变原有函数时就会用到装饰器。装饰器在python中是非常常用且重要的功能,是一种python的语法糖。

在理解装饰器之前先看下面的加法函数:

def add(x,y):
    return x + y

若想增加信息输出功能:

def add(x,y):
    prtint("output")
    return x + y

这样修改耦合太高,并且侵入了原有的业务代码。我们可以改成这样:

def add(x,y):
    return x + y

def test(fn):
    print('begin') # 增强的输出
    print('end') # 增强的功能
    return fn

print(test(add)(4,5))

使函数test()更便捷的传参:

def add(x,y):
    return x + y

def test(fn,*args,**kwargs): #相当于是*args,**kwargs作为参数传给fn这一函数对象。
    print('begin') # 增强的输出
    print('end') # 增强的功能
    return fn(*args,**kwargs) #

print(test(add,4,23))

对test()函数进行柯里化,让它只接收函数对象:

def test(fn):
    def wrapper(*args,**kwargs):
        print("hello")
        print("world")
        return fn(*args,**kwargs)
    return wrapper

print(test(add)(3,6))

使用装饰器:

def test(fn):
    def wrapper(*args,**kwargs):
        print("hello")
        print("world")
        return fn(*args,**kwargs)
    return wrapper

@test #等价于add = test(add)
def add(x,y):
    return x + y

@test #用test()函数再对add1()函数进行一次装饰,等价于add1 = test(add1)
def add1(x,y,z):
    return x + y + z

print(add(x=4,y=6))
print(add1(3,5,43))

可以理解为装饰器是用一个函数将另一个函数装饰了一次,在这里看似调用的是add()和add1()函数,但实际上调用的是test()函数,再由test()函数返回wrapper函数对象将参数传给内部fn()函数,test()函数中的参数是什么,fn()函数就是什么。(装饰器的用@表示。)

Categories: Python

发表评论

电子邮件地址不会被公开。 必填项已用*标注