1.partial
首先是partial函数,它可以重新绑定函数的可选参数,生成一个callable的partial对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
>>> int ( '10' ) # 实际上等同于int('10', base=10)和int('10', 10) 10 >>> int ( '10' , 2 ) # 实际上是int('10', base=2)的缩写 2 >>> int2 = partial( int , 2 ) # 这里我没写base,结果就出错了 >>> int2( '10' ) Traceback (most recent call last): File "<stdin>" , line 1 , in <module> TypeError: an integer is required >>> int2 = partial( int , base = 2 ) # 把base参数绑定在int2这个函数里 >>> int2( '10' ) # 现在缺省参数base被设为2了 2 >>> int2( '10' , 3 ) # 没加base,结果又出错了 Traceback (most recent call last): File "<stdin>" , line 1 , in <module> TypeError: keyword parameter 'base' was given by position and by name >>> int2( '10' , base = 3 ) 3 >>> type (int2) < type 'functools.partial' > |
从中可以看出,唯一要注意的是可选参数必须写出参数名。
2.update_wrapper
接着是update_wrapper函数,它可以把被封装函数的__name__、__module__、__doc__和 __dict__都复制到封装函数去:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#-*- coding: gbk -*- def thisIsliving(fun): def living( * args, * * kw): return fun( * args, * * kw) + '活着就是吃嘛。' return living @thisIsliving def whatIsLiving(): "什么是活着" return '对啊,怎样才算活着呢?' print whatIsLiving() print whatIsLiving.__doc__ print from functools import update_wrapper def thisIsliving(fun): def living( * args, * * kw): return fun( * args, * * kw) + '活着就是吃嘛。' return update_wrapper(living, fun) @thisIsliving def whatIsLiving(): "什么是活着" return '对啊,怎样才算活着呢?' print whatIsLiving() print whatIsLiving.__doc__ |
结果:
1
2
3
4
5
|
对啊,怎样才算活着呢?活着就是吃嘛。 None 对啊,怎样才算活着呢?活着就是吃嘛。 什么是活着 |
不过也没多大用处,毕竟只是少写了4行赋值语句而已。
3.wraps
再有是wraps函数,它将update_wrapper也封装了进来:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#-*- coding: gbk -*- from functools import wraps def thisIsliving(fun): @wraps (fun) def living( * args, * * kw): return fun( * args, * * kw) + '活着就是吃嘛。' return living @thisIsliving def whatIsLiving(): "什么是活着" return '对啊,怎样才算活着呢?' print whatIsLiving() print whatIsLiving.__doc__ |
结果还是一样的:
1
2
|
对啊,怎样才算活着呢?活着就是吃嘛。 什么是活着 |
4.total_ordering
最后至于total_ordering函数则给予类丰富的排序方法,使用装饰器简化了操作。如果使用必须在类里面定义一个__lt__(),__le__(), __gt__(), 或__ge__()。应该给类添加一个__eq__() 方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
from functools import total_ordering @total_ordering class Student( object ): def __init__( self , name): self .name = name def __eq__( self , other): return self .name.lower() = = other.name.lower() def __lt__( self , other): return self .name.lower() < other.name.lower() a = Student( 'dan' ) b = Student( 'mink' ) print a > b print a print sorted ([b, a]) |
打印结果
1
2
3
|
False <__main__.Student object at 0x7f16ecb194d0> [<__main__.Student object at 0x7f16ecb194d0>, <__main__.Student object at 0x7f16ecb195d0>] |