Python 装饰器

 

 

1、原函数有多个参数的情况,计算函数运行时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import time
 
def 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
 
@performance
def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
 
print factorial(10)

2、带参数的装饰器

1
原理:
1
2
3
4
5
6
7
8
9
10
11
12
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():
    pass
print test()
1
  
1
实例代码:
1
上一节的@performance只能打印秒,请给 @performace 增加一个参数,允许传入's''ms'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time
 
def performance(unit):
    def unit_decorator(f):
        def wrapper(*args,**kw):
            t1 = time.time()
            r=f(*args,**kw)
            t2 = time.time()
     
            print 'call %s() in %fs %s'% (f.__name__,(t2-t1),unit)
            return r
        return wrapper
    return unit_decorator
     
 
@performance('ms')
def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
 
print factorial(10)

3、将原函数属性(name、doc等)复制到warpper函数中

原理:

1
2
3
4
5
6
7
import functools
def log(f):
    @functools.wraps(f)
    def wrapper(*args, **kw):
        print 'call...'
        return f(*args, **kw)
    return wrapper

实例:

请思考带参数的@decorator,@functools.wraps应该放置在哪:

@functools.wraps(f) 这句代码应该放置在函数 f 定义之后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time, functools
 
def performance(unit):
     
    def perf_decorator(f):
        @functools.wraps(f)
        def wrapper(*args,**kw):
            t1 = time.time()
            r=f(*args,**kw)
            t2 = time.time()
            print 'call %s() in %fs %s'% (f.__name__,(t2-t1),unit)
            return r
        return wrapper
    return perf_decorator   
 
@performance('ms')
def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
 
print factorial.__name__

4、偏函数@functools.partial

functools.partial能够减少函数的参数,少的参数需要在创建时指定默认值。

1
2
3
4
import functools
int2 = functools.partial(int, base=2)
int2('1000000')
例子:
1
sorted(iterable, cmp = None, key = None, reverse = False),返回值为一个新的列表list
1
可以在sorted cmp参数位置传入自定义排序函数,用functools.partial可以把它简化。
1
代码1
1
2
3
import functools
sorted_ignore_case = functools.partial(sorted, cmp=lambda s1, s2: cmp(s1.upper(), s2.upper()))
print sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit'])

(代码中s1.upper()都换成lower()也可以)

代码2:

1
2
3
import functools
sorted_ignore_case = functools.partial(sorted, key = str.lower)
print sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit'])
1
  
原文地址:https://www.cnblogs.com/xc1234/p/9129490.html