您的位置:首页 > 其它

7.2 functools--高阶函数和可调用对象

2016-02-28 08:57 393 查看
本模块主要提供了高阶函数和可调用对象。
functools.cmp_to_key(func)
转换旧类型的比较函数为一个键值函数。主要用来转换Python版本2的函数参数,比如在函数sorted(),miin(),max(),heapq.nlargest()。
例子:
#python 3.4
from functools import *

l = [2, 8, 1, 3]
def num_cmp(x, y):
return x - y
r = sorted(l, key = cmp_to_key(num_cmp))
print(r)
结果输出如下:
[1, 2, 3, 8]

@functools.lru_cache(maxsize=128, typed=False)
lru_cache函数是一个装饰器函数,它主要用来缓存最近调用的结果,这样提高函数调用效率,不用每次都重新计算。参数maxsize是缓存多少次,设置为None时表示不限制缓存的次数,但会占用比较多内存;参数typed是用来是否分不同类型来保存函数返回值,如果设置为True就进行区分,比如f(3)和f(3.0)就会区分不同地方保存;设置为False就不作这样的区分保存。由于使用一个字典保存缓存结果,所以有的位置参数和关键值参数都需要是可以hash保存的。
例子:
#python 3.4
from functools import *

@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
r = [fib(n) for n in range(16)]
print(r)
print(fib.cache_info())
结果输出如下:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

@functools.total_ordering
提供一个类拥有所比较方法的装饰器。比如你想写一个排序类时,需要写大于、等于、小于等等比较实现,如果每个都重载要写比较多的代码,而这个装饰器提供了一个方式,只要实现自己需要的比较函数即可,其它使用装饰里的默认实现。
例子:
@total_ordering
class Student:
def _is_valid_operand(self, other):
return (hasattr(other, "lastname") and
hasattr(other, "firstname"))
def __eq__(self, other):
if not self._is_valid_operand(other):
return NotImplemented
return ((self.lastname.lower(), self.firstname.lower()) ==
(other.lastname.lower(), other.firstname.lower()))
def __lt__(self, other):
if not self._is_valid_operand(other):
return NotImplemented
return ((self.lastname.lower(), self.firstname.lower()) <
(other.lastname.lower(), other.firstname.lower()))

functools.partial(func, *args, **keywords)
返回一个固定部分参数的函数对象。比如想调用一个函数有五个参数,但在使用过程中发现有三个参数是需要固定的,不改变的,就可以采用这个方法来绑定这几个参数,从而达到简化,不让后面的代码进行修改。
例子:
#python 3.4
from functools import *

def add(a, b):
return a + b
r = partial(add, 10)
print(r)
print(r(1)) #10 + 1
print(r(2)) #10 + 2
结果输出如下:
functools.partial(<function add at 0x02D879C0>, 10)
11
12

class functools.partialmethod(func, *args, **keywords)
本函数与上面的函数的意义是一样的,只不过本函数只是针对类里的方法进行绑定参数。
例子:
#python 3.4
from functools import *

class Cell(object):
def __init__(self):
self._alive = False
@property
def alive(self):
return self._alive
def set_state(self, state):
self._alive = bool(state)
set_alive = partialmethod(set_state, True)
set_dead = partialmethod(set_state, False)

c = Cell()
print(c.alive)
c.set_alive()
print(c.alive)
结果输出如下:
False
True

functools.reduce(function, iterable[, initializer])
把一个两个参数的函数function应用到一个序列上进行迭代操作。比如reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])就会这样计算:((((1+2)+3)+4)+5)。它的实现等同于下面的代码:
def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
value = next(it)
else:
value = initializer
for element in it:
value = function(value, element)
return value
例子:
#python 3.4
from functools import *

def statistics(dic,k):
if not k in dic:
dic[k] = 1
else:
dic[k] +=1
return dic
lst = [1, 2, 3, 4]
print(reduce(statistics, lst, {}))
结果输出如下:
{1: 1, 2: 1, 3: 1, 4: 1}

@functools.singledispatch(default)
本装饰器用来实现函数对多个类型进行重载。比如同样的函数名称,对不同类型有不同功能实现。
例子:
#python 3.4
from functools import *

@singledispatch
def fun(arg, verbose = False):
if verbose:
print('singledispatch:', end = ' ')
print(arg)
@fun.register(list)
def _(arg, verbose = False):
if verbose:
print('list:')
for i, elem in enumerate(arg):
print(i, elem)

fun(100, verbose = True)
fun([1, 2, 3], verbose = True)
结果输出如下:
singledispatch: 100
list:
0 1
1 2
2 3

functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
更新函数wapper像wrapped函数一样的,主要共用相同的描述字符串。
例子:
#python 3.4
from functools import *

def updateTest(fun):
def living(*args, **kw):
return fun(*args, **kw) + ' best'
return update_wrapper(living, fun)
@updateTest
def Caimouse():
"blog.csdn.net/caimouse"
return 'Python'
print(Caimouse())
print(Caimouse.__doc__)
结果输出如下:
Python best
blog.csdn.net/caimouse

@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
本函数是把上面的函数进行封装,提供的功能是一样的。
例子:
#python 3.4
from functools import *

def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
print('Calling decorated function')
return f(*args, **kwds)
return wrapper

@my_decorator
def example():
"""Docstring"""
print('Called example function')

example()
print(example.__doc__)
结果输出如下:
Calling decorated function
Called example function
Docstring

蔡军生 QQ:9073204 深圳
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: