Python之装饰器——从稀里糊涂到完全搞定

开始前的闲谈:
最近Python越发火热,不管是炒作还是真火,相信每个火爆的事物,背后总有一个不可替代的原因。总的来看,Python之所以火是因为其语法简单,灵活,非常适合初学者,让“从入门到放弃”的时间有所拉长。有人说Python并不能让你独当一面,或者说只掌握Python不能成为一个“能走得更远”的程序员。我认为与其担心、观望、往复纠结,不如踏踏实实先掌握它。老实想想,自己真的“掌握了Python吗?”,我相信真正掌握后,对于继续学习和使用其它语言也是不无帮助的。

言归正传:
接下来分析一点Python之装饰器,希望能够让大家有所参考~
水平有限,有错误大家评论区直接骂!我们的目的是技术成长!
还在呼吸就在学习,让我们一起,在学习的路上一去不返。

先来看一个例子,判断一个数字是否能被3整除:

def is_div_three(num):
    return num % 3 == 0

print(is_div_three(6))

运行结果显然是True
接下来,例如我们需要打印1-10000里能被3整除的数,很简单:

def nums_is_div_tree():
    for i in range(1, 10000):
        if is_div_three(i):
            print(i)

nums_is_div_tree()

输出结果是一连串能被3整除的数字。试想我们又有一个需求,想知道这个程序运行的效率,即求运行时间,显然我们可以把上面的函数进行改造:

import time #引入time模块
def time_is_div_tree():
    t1 = time.time() #在执行循环前先记录系统时间
    for i in range(1, 10000):
        if is_div_three(i):
            print(i)
    t2 = time.time() #在执行循环后再次记录时间
    return t2-t1    #两个时间相减获得运行时间

t = time_is_div_tree()
print(t)

执行结果,除了打印出能被3整除的数外,还获得了运行时间:
在这里插入图片描述
我们来思考,这种方式求运行时间是否为最佳方案?
试想,我们定义了几十个函数,当我们需要去关注某些函数的运行时间,就要去修改这些函数,加上求时间的代码,有没有一种方式更加简便?装饰器就可以解决这个问题~继续看:
我们定义一个求运行时间的装饰器:

def print_time(func): #装饰器本身是一个函数,参数func是需要执行的函数
    def wrapper():
        t1 = time.time()
        func()
        t2 = time.time()
        print('running time: {} s'.format(t2-t1))
    return wrapper

然后,在上面的nums_is_div_tree()函数上加一行:@print_time:

@print_time
def nums_is_div_tree():
    for i in range(1, 10000):
        if is_div_three(i):
            print(i)

nums_is_div_tree()

看下效果:除了输出了1-10000里能被3整除的数,还打印出了运行时间:
在这里插入图片描述
这样,我们需要求哪个函数的运行时间,只要在函数前加上一行@print_time装饰器即可,有没有很方便!
至此,装饰器我们了解了一半。有人会问,如果求n以内能被3整除的数呢?显然我们需要传入一个参数,那么我们修改以上函数:

@print_time
def nums_is_div_tree(maxnum):  #使用传入maxnum
    for i in range(1, maxnum):
        if is_div_three(i):
            print(i)
nums_is_div_tree(10000)

运行报错:
原因是wrapper不能传入参数
原因是wrapper不能传入参数,我们需要修改上述ptint_time装饰器,在wrapper函数中传入参数:

def print_time(func): #装饰器本身是一个函数,参数func是需要执行的函数
    def wrapper(arg): #在wrapper中传入参数arg
        t1 = time.time()
        func(arg)     #将arg传入需要执行的函数
        t2 = time.time()
        print('running time: {} s'.format(t2-t1))
    return wrapper

运行一切正常~
在这里插入图片描述
又有人提出需求,如果装饰器本身也带有参数呢?比如,求运行时间时,我们需要打印出一段文字:“装饰器print_time正在执行中”
我们再去修改装饰器:

def print_time(text): #这里传入参数
    def decorator(func):  #嵌套decorator函数来接收需要执行的函数func
        def wrapper(arg): #在wrapper中传入参数arg
            t1 = time.time()
            func(arg)     #将arg传入需要执行的函数
            t2 = time.time()
            print(text)
            print('running time: {} s'.format(t2-t1))
        return wrapper
    return decorator

继续执行:

@print_time('装饰器print_time正在执行中') #传入我们需要打印的内容
def nums_is_div_tree(maxnum):
    for i in range(1, maxnum):
        if is_div_three(i):
            print(i)

nums_is_div_tree(10000)

运行结果,拿到了我们想要的结果:
在这里插入图片描述
至此,Python装饰器讨论结束,有没有感觉豁然开朗呢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值