三、装饰器
1、装饰器是在函数调用之上的修饰
2、这些修饰仅是当声明一个函数或者方法的时候,才会应用的额外调用
3、使用装饰器的情形有:
3.1引入日志
3.2 增加计时逻辑来检测性能
3.3 给函数加入事务的能力
装饰器基础:
1、装饰是为函数和类指定管理代码的一种方式。
2、装饰器本身的形式是处理其他的可调用对象的可调用的对象( 如函数)
Python装饰器以两种相关的形式呈现
1、函数装饰器在函数定义的时候进行名称重绑定, 提供一个逻辑层来管理函数和方法或随后对它们的调用。
2、类装饰器在类定义的时候进行名称重绑定, 提供一个逻辑层来管理类, 或管理随后调用它们所创建的示例
函数装饰器安装包装器对象, 以在需要的时候拦截随后的函数调用并处理它们
类装饰器安装包装器对象, 以在需要的时候拦截随后的实例创建调用并处理它们
函数装饰器可以用来管理函数调用和函数对象, 类装饰器可以用来管理类实例和类自身
当主体函数或类定义的时候, 装饰器应用一次; 在对类或函数的每次调用的时候,不必添加额外的代码( 在未来可能必须改变)
函数装饰器
1、它们主要只是一种语法糖: 通过在一个函数的def语句的末尾来运行另一个函数, 把最初的函数名重新绑定到结果
用法
函数装饰器是一种关于函数的运行时声明, 函数的定义需要遵守此声明。 装饰器在紧挨
着定义一个函数或方法的d e f语句之前的一行编写, 并且它由@符号以及紧随其后的对于
元函数的一个引用组成——这是管理另一个函数的一个函数( 或其他的可调用对象)
deco1.py内容:
#!/usr/bin/env python #coding:utf8 import time def loop(): result = [] for i in range(1,6): result.append(i) time.sleep(1) return result if __name__ == "__main__": start = time.time() print loop() end = time.time() print "program cost %5.3f seconds " % (end -start)
执行结果:
[1, 2, 3, 4, 5] program cost 5.002 seconds
deco2.py内容:
#!/usr/bin/env python #coding:utf8 import time def timeit(func): start = time.time() res = func() end = time.time() print "program cost %5.3f seconds " % (end -start) return res def loop(): result = [] for i in range(1,6): result.append(i) time.sleep(1) return result if __name__ == "__main__": print timeit(loop)
执行结果:
program cost 5.002 seconds [1, 2, 3, 4, 5]
deco3.py内容:
#!/usr/bin/env python #coding:utf8 import time def deco(func): def timeit(): start = time.time() res = func() end = time.time() print "program cost %5.3f seconds " % (end -start) return res return timeit @deco def loop(): result = [] for i in range(1,6): result.append(i) time.sleep(1) return result if __name__ == "__main__": print loop()
执行结果:
program cost 5.019 seconds [1, 2, 3, 4, 5]
color_font1.py内容:
#!/usr/bin/env python #coding:utf8 def color(func): def color_font(): return "\033[31;1m%s\033[0m" % func() return color_font @color def say_hi(): return "Hello world" @color def greet(): return "Welcome bob" if __name__ == "__main__": print say_hi() print greet()
执行结果:
Hello world Welcome bob
color_font2.py内容:
#!/usr/bin/env python #coding:utf8 def color(func): def color_font(*args): return "\033[31;1m%s\033[0m" % func(*args) return color_font @color def say_hi(): return "Hello world" @color def greet(name): return "Welcome %s" % name if __name__ == "__main__": #print say_hi() print greet(‘bob‘)
执行结果:
Welcome bob
输出程序运行起止时间
写 deco.py 脚本,主要要求如下:
1、 编写一个循环 10 次的函数,每次循环睡眠 1 秒
2、函数运行前打印当前时间
3、函数运行结束后打印结束时间
4、使用装饰器的方式实现
方案
装饰器是在函数调用之上的修饰。这些修饰仅是当声明一个函数或者方法的时候,才会应用的额外调用。
在一个程序内部打印起止时间是可以的,但是如果很多程序都有相同的要求,那么就要
不断的去编写重复的代码。简单的使用闭包,执行程序成为闭包函数的参数,用起来显得不那么友好、方便。
使用装饰器,只需要在函数定义时额外加个装饰即可,调用函数时还是调用原始定义
的函数,不是将其作为其他函数的参数。既方便使用,又保持了函数原始的形态
#!/usr/bin/env python #coding:utf-8 import time def deco(func): #定义用于装饰器的函数 def timeit(): print ‘prog start at:‘, time.ctime() newList = func() print ‘prog done at:‘, time.ctime() return newList return timeit @deco #定义函数时调用装饰器函数 def loop2(n = 10): myList = [] for i in range(n): if i % 2: myList.append(i) time.sleep(1) return myList if __name__ == ‘__main__‘: print loop2()
执行结果:
prog start at: Tue Aug 01 14:14:14 2017 prog done at: Tue Aug 01 14:14:24 2017 [1, 3, 5, 7, 9]