python装饰器 稀里糊涂_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整除的数外,还获得了运行时间:

20200408171150580.png

我们来思考,这种方式求运行时间是否为最佳方案?

试想,我们定义了几十个函数,当我们需要去关注某些函数的运行时间,就要去修改这些函数,加上求时间的代码,有没有一种方式更加简便?装饰器就可以解决这个问题~继续看:

我们定义一个求运行时间的装饰器:

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整除的数,还打印出了运行时间:

20200408173852881.png

这样,我们需要求哪个函数的运行时间,只要在函数前加上一行@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)

运行报错:

20200408175336406.png

原因是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

运行一切正常~

20200408175758300.png

又有人提出需求,如果装饰器本身也带有参数呢?比如,求运行时间时,我们需要打印出一段文字:“装饰器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)

运行结果,拿到了我们想要的结果:

20200408180637801.png

至此,Python装饰器讨论结束,有没有感觉豁然开朗呢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值