首页 > 代码库 > 第十篇:装饰器

第十篇:装饰器

三、装饰器
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]

 

第十篇:装饰器