[置顶] Python3装饰器的用法和心得,及装饰器作业
2018-02-22 21:18
656 查看
本文基于廖雪峰老师课程Python3写成,在学习过程当中会经常的发散性思维,力求把所有能考虑到的情况都考虑完全。(本文编辑器为Sublime Text3)
1、装饰器的用法和心得a.下面为原代码:
def log(func): def wrapper(*args,**kw): print('call%s():'%func.__name__) return func(*args,**kw) return wrapper @log def now(): print('2018-2-22') now()
得出结果:
callnow(): 2018-2-22 [Finished in 0.2s]
b.下面逐步讨论上面这个代码:
def log(func): def wrapper(*args,**kw): print('call%s():'%func.__name__) return func(*args,**kw) return wrapper @log def now(): print('2018-2-22')
这看上去像一段返回函数,不过需要注意的有两点。
第一点:
括号里面的func参数到时候赋值进去的是一段新函数,@log下面的函数块
def now(): print('2018-2-22')
会产生一个一模一祥的函数块到func参数里面去,而不是它自己本身赋值进去。(@+需要调用的函数,@log函数代表调用log函数,(函数如果没有人调用它们则不会运行)下面必须还需要自己写一段函数作为赋值的参数)。
第二点:
wrapper(*args,**kw)
wrapper()括号里面的*args,**kw前面的星号都是必要的,如果没有将会产生错误
TypeError: wrapper() missing 1 required positional argument: 'args'
而这两个星号的参数需要放在哪儿呢,及当@log下面的函数
def now(): print('2018-2-22')
=
(一个函数)
def wrapper(*args,**kw):#这里面的*args,*kw其实已经被'新'函数def now(): print('2018-2-22')赋值或者说替代掉了。
print('call%s():'%func.__name__)
return func(*args,**kw)
的时候,就需要在后边的函数参数里面写入*args,**kw(代表可以传入任何参数,廖雪峰老师说:now = log(now)。就是我把老师的公式给展开来)。还有一点需要注意:最后调用
now()
函数得到的不是print(‘2018-2-22’),而是
def wrapper(*args,**kw): print('call%s():'%func.__name__) return func(*args,**kw)
这个代码块的结果,也许这就是@的用法吧。。。
第三点:我们来讨论一下,一个星号和两个星号的区别(不局限于上面代码):
1、一个星号*的用法:
代表可以传入任何非关键字,显示出来的就会变成一个元组,看下面代码:
def prints(*arg): print (arg); print(prints (1,2,3,4,5,6,7))
打印的结果是一个元组: (1,2,3,4,5,6,7) , 也就是说该参数(arg) 将传进来的所有参数放在了一个元组中。
2、两个星号的用法
传入关键字,显示出来的就是一个dic,有key和value值。(所以在有两个星号的参数中我们需要传入两个参数作为一组,比如:a=1,b=2,c=3,d=4,e=5,f=6,g=7),代码如下:
def dics(**arg): print (arg) print(dics(a=1,b=2,c=3,d=4,e=5,f=6,g=7))
结果为:
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7}
课后作业:
import time,functools def metric(fn): @functools.wraps(fn) def log(*args,**kw): print('fn():%s'%time.ctime())(这里可以不用加) print(fn(*args,**kw)) return log @metric def fast(x,y): time.sleep(0.0012) return x+y; @metric def slow(x,y,z): time.sleep(0.1234) return x*y*z; f=fast(11,22) s=slow(11,22,33) if f !=33: print('测试失败') elif s!=7986: print('测试失败')
结果为:
fn():Fri Feb 23 21:02:55 2018 33 fn():Fri Feb 23 21:02:55 2018 7986 测试失败
为什么不出现测试失败呢,因为我在代码中加入了这一行代码
print('fn():%s'%time.ctime()),结果会出现
fn():Fri Feb 23 21:02:55 2018所以会判断出错,把这一行代码去掉就可以了。
相关文章推荐
- C++用法的学习心得
- [置顶] 关于对js插件fullpage学习的一些心得
- C++用法的学习心得(要求包含示例,并反映出利用网络获取帮助的过程)
- go语言fallthrough的用法心得
- 基于jquery的异步ztree树形插件的用法和心得
- [转]pack/unpack用法--心得筆記
- 关于ActionContext.getContext()的用法心得
- [置顶] 一位ACMer过来人的心得
- [置顶] Burp Suite中proxy的简单用法
- MFC对话框置顶 SetWindowPos()的用法(三)
- [置顶] Hadoop作业运行(OOM)内存溢出错误分类和参数调优化
- c#中分页打印(预览)HasMorePages的用法心得
- [置顶] day15.要点回顾和新指令的用法
- 置顶窗口SetWindowPos()的用法
- [置顶] 【scala 匹配模式】match case|case class |::|:::|=>用法
- setInterval()函数的用法心得
- iOS CornerStone的用法和心得
- [置顶] 开源项目几点心得,Java架构必会几大技术点
- [置顶] MYSQL 中group by,order by用法详解及其特殊用法
- from __future__ import absolute_import用法心得小结