python之装饰器

python之装饰器

想理解python装饰器,首先需要了解高阶函数和内嵌函数,这些在上一篇函数中有介绍,这里就不赘述了。
装饰器的作用就是装饰一个函数,给这个函数增加某些功能。
为什么要使用装饰器呢?因为一个函数已经实现了某些具体的功能,而我们想要增加某些功能,但是又不希望修改源代码,避免增加不必要的问题,而且也不修改其调用方式(可能存在很多调用,不想全部找到并修改)。

下面我们逐步来讲解:
回调函数

import time

def deco(func):
    star_time = time.time()
    ret = func()
    end_time = time.time()
    print("running time is %s" % (end_time - star_time))
    return ret     # 加上返回值,若原函数func的返回值有用,我们也需要将其返回

def test1():
    time.sleep(2)
    print("in the test1")

#test1()   # 原调用方式
deco(test1) # 新调用方式

很明显上面那段代码我们修改了函数的调用方式。
在看下面:

import time
def timer(func):
    def deco():
        star_time = time.time()
        ret = func()
        end_time = time.time()
        print("running time is %s" % (end_time - star_time))
        return ret     # 加上返回值,若原函数func的返回值有用,我们也需要将其返回
    return deco


def test1():
    time.sleep(2)
    print("in the test1")

test1 = timer(test1)
test1()

上面的代码基本上就实现了装饰器的功能了,我们没有修改原函数,也没有修改函数的调用方式,只是在该函数的定义后加上了funcname = decorator(funcname)

下面我们来看下真正的装饰器是怎么样的:

def timer(func):
    def deco():
        star_time = time.time()
       ret =  func()
        end_time = time.time()
        print("running time is %s" % (end_time - star_time))
        return ret     # 加上返回值,若原函数func的返回值有用,我们也需要将其返回
    return deco

@timer    #实际上就是 test1 = timer(test1),不同点在于,在函数定义前。
def test1():
    time.sleep(2)
    print("in the test1")

print(test1.__name__)    # 看一下我们调用的函数名
test1()
deco
in the test1
running time is 2.0000593662261963

对比上面代码和第二段代码,我们可以发现,实际上的区别就只有一句话而已,@是python内部提供的方法,当然,必须放在修饰的函数前。
而函数名也恰恰证明了我们的猜想,修饰后,test1调用的函数确实是deco函数。

如果我们修饰的函数有参数该怎么处理呢(一个装饰器可能修饰多个不同的函数,参数个数也不一致)?请看下面的代码:

def log(func):
    def deco(*args,**kwargs):
        print("log:",func.__name__)
        return func(*args,**kwargs)
    return deco

@log
def test(str):
    print("in the test: ",str)

test("hello")

上面我们之前学的可变参数就排上用场了,这样装饰器就可以装饰形参数不同的函数了。

如果说我们的装饰函数需要接收参数呢?那么我们就需要三级嵌套了:

def log(str):
    def deco(func):
        def note(*args):
            print("%s : %s" % (str,"this is decorator!"))
            return func()
        return note
    return deco

    
@log("sylvain")   #相当于 test1 = log("sylvain")(test1)
def test1():
    print("in the test1")
print(test1.__name__)
test1()

好了,关于装饰器就知道这么多了,有错误欢迎指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值