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

Posted caimouse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7.2 functools--高阶函数和可调用对象相关的知识,希望对你有一定的参考价值。

本模块主要提供了高阶函数和可调用对象。

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) 

更新函数wapperwrapped函数一样的,主要共用相同的描述字符串。

例子:

#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  深圳

以上是关于7.2 functools--高阶函数和可调用对象的主要内容,如果未能解决你的问题,请参考以下文章

python 之 functools模块

functools模块

python标准库--functools.partial

python functools.partial

使用迭代器的可调用对象的名称? [关闭]

python中的functools模块