Python学习笔记(六):decorator装饰器

来源:互联网 发布:ipad刷机软件mac版 编辑:程序博客网 时间:2024/04/29 07:49

一、装饰器的用途和作用

装饰器,一种高阶函数的表达方法,传入函数,返回函数。

将需要完善的函数作为参数 传入高阶函数,在高阶函数内,调用这个函数,并返回一个函数名,代替待完善函数。


用途:已经定义了函数,想动态改变函数功能,又不想改变原函数的代码时,可以使用装饰器。

装饰器作用:

可以极大地简化代码,避免每个函数编写重复性代码

.Python内置的@语法就是为了简化装饰器调用;

打印日志:@log
检测性能:@performance
数据库事务:@transaction

URL路由:@post('/register')


二、无参数的decorator

要让 @log 自适应任何参数定义的函数,可以利用Python的 *args 和 **kw,保证任意个数的参数总是能正常调用:

*args可以当作可容纳多个变量组成的tuple

**kw可以当作容纳多个key和value的dict
同时使用*args和**kws时,必须*args参数列要在**kw前


栗子:计算函数调用的时间可以记录调用前后的当前时间戳,然后计算两个时间戳的差。

import timedef performance(f):    def fn(*args,**kw):        t1=time.time()        r=f(*args,**kw)        t2=time.time()        print 'call %s() in %fs'%(f.__name__,(t2-t1))        return r    return fn@performancedef factorial(n):    return reduce(lambda x,y: x*y, range(1, n+1))print factorial(10)


三、带参数的decorator

带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数:

栗子:

def log(prefix):    def log_decorator(f):        def wrapper(*args, **kw):            print '[%s] %s()...' % (prefix, f.__name__)            return f(*args, **kw)        return wrapper    return log_decorator@log('DEBUG')def test():    passprint test()


四、完善decorator

由于decorator返回的新函数函数名已经不是原函数,而是@log内部定义的。这对于那些依赖原函数名的代码就会失效。decorator还改变了函数的__doc__等其它属性。如果要让调用者看不出一个函数经过了@decorator的“改造” ,就需要把原函数的一些属性复制到新函数中。
Python内置的functools可以用来自动化完成这个“复制”的任务,@functools.wraps应该作用在返回的新函数上。
最后需要指出,由于我们把原函数签名改成了(*args, **kw),因此,无法获得原函数的原始参数信息。即便我们采用固定参数来装饰只有一个参数的函数。

栗子:
import functoolsdef log(f):    @functools.wraps(f)    def wrapper(*args, **kw):        print 'call...'        return f(*args, **kw)    return wrapper


五、偏函数

当一个函数有很多参数时,调用者就需要提供多个参数。如果减少参数个数,就可以简化调用者的负担。

functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

0 0
原创粉丝点击