python 中的装饰器和生成器用法详解:

装饰器函数

装饰器里引入通用功能处理

1.引入日志

2.函数执行时间统计

3.执行函数前预备处理

4.执行函数后清理功能

例1:无参数的函数

#decorator.py
from time import ctime, sleep

def timefun(func):
    def wrappedfunc():
        print "%s called at %s"%(func.__name__, ctime())
        return func()
    return wrappedfunc

@timefun
def foo():
    pass

foo()
sleep(2)
foo()

例2:被装饰的函数有参数

#decorator2.py
from time import ctime, sleep

def timefun(func):
    def wrappedfunc(a, b):
        print "%s called at %s"%(func.__name__, ctime())
        print a, b
        return func(a, b)
    return wrappedfunc

@timefun
def foo(a, b):
    print a+b

foo(3,5)
sleep(2)
foo(2,4)

例3:装饰器带参数,在原有装饰器的基础上,设置外部变量

#decorator2.py
from time import ctime, sleep

def timefun_arg(pre="hello"):
    def timefun(func):
        def wrappedfunc():
            print "%s called at %s %s"%(func.__name__, ctime(), pre)
            return func()
        return wrappedfunc
    return timefun

@timefun_arg("itcast")
def foo():
    pass

@timefun_arg("xwp")
def too():
    pass

foo()
sleep(2)
foo()

too()
sleep(2)
too()

例4:装饰器和闭包混用(难)

#coding=utf-8

from time import time

def logged(when):
    def log(f, *args, **kargs):
        print "fun:%s  args:%r  kargs:%r" %(f, args, kargs) 
        #%r字符串的同时,显示原有对象类型

    def pre_logged(f):
        def wrapper(*args, **kargs):
            log(f, *args, **kargs)
            return f(*args, **kargs)
        return wrapper

    def post_logged(f):
        def wrapper(*args, **kargs):
            now=time()
            try:
                return f(*args, **kargs)
            finally:
                log(f, *args, **kargs)
                print "time delta: %s"%(time()-now)
        return wrapper
    try:
        return {"pre":pre_logged, "post":post_logged}[when]
    except KeyError, e:
        raise ValueError(e), 'must be "pre" or "post"'

@logged("post")
def fun(name):
    print "Hello, ", name

fun("itcastcpp!")

生成器函数

生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。

生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。 生成器的特点:

 1.生成器是一个函数,而且函数的参数都会保留。
 2.迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
 3.节约内存

例子:执行到yield时,gen函数作用暂时保存,返回x的值;tmp接收下次c.send("python"),send发送过来的值,c.next()等价c.send(None)

#generation.py
def gen():
    for x in xrange(4):
        tmp = yield x
        if tmp == "hello":
            print "world"
        else:
            print "itcastcpp ", str(tmp)

>>>from generation import gen
>>>c=gen()
>>>c.next()
0
>>>c.next()
itcastcpp None
1
>>>c.send("python")
itcastcpp python
2

posted on 2016-08-04 00:55  A-祥子  阅读(455)  评论(0)    收藏  举报

导航