该模块为高阶函数提供支持——作用于或返回函数的函数被称为高阶函数。在该模块看来,一切可调用的对象均可视为本模块中所说的“函数”。

  目录

  一、模块方法

    1. functools.cmp_to_key(func)

    2. functools.total_ordering(cls)

    3. functools.reduce(function, iterable[, initializer])

    *4. functools.partial(func[,*args][, **keywords])

    5. functools.update_wrapper(wrapper, wrapped[, assigned][, updated])

    *6. functools.wraps(wrapped[, assigned][, updated])

  二、partial对象

    1. partial.func

    2. partial.args

    3. partial.keywords

一、模块方法

  该模块中定义了如下方法:

1.

functools.cmp_to_key(func)

  将老式的比较函数(comparison function)转化为关键字函数(key function)。与接受key function的工具一同使用(如 sorted(), min(), max(), heapq.nlargest(), itertools.groupby())。该函数主要用来将程序转成 Python 3 格式的,因为 Python 3 中不支持比较函数。

  比较函数是可调用的,接受两个参数,比较这两个参数并根据他们的大小关系返回负值、零或正值中的某一个。关键字函数也是可调用的,接受一个参数,同时返回一个可以用作排序关键字的值。

  例如:

sorted(iterable, key=cmp_to_key(locale.strcoll))

2.

functools.total_ordering(cls)

  这是一个类装饰器,给定一个类,这个类定义了一个或多个比较排序方法,这个类装饰器将会补充其余的比较方法,减少了自己定义所有比较方法时的工作量。

  被修饰的类必须至少定义 __lt__(), __le__(), __gt__() 或 __ge__() 中的一个,同时,被修饰的类还应该提供 __eq__() 方法。

  例如:

@total_ordering
class Student:
def __eq__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) ==
(other.lastname.lower(), other.firstname.lower()))
def __lt__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) <
(other.lastname.lower(), other.firstname.lower()))

3.

functools.reduce(function, iterable[, initializer])

  和 reduce() 方法的作用相同,这里提供了向 Python 3 过渡的前向支持。

4.

functools.partial(func[,*args][, **keywords])

  函数装饰器,返回一个新的 partial 对象,关于 partial 对象的介绍见下文。调用 partial 对象就和调用被修饰的函数 func 相同,只不过调用 partial 对象时传入的参数个数通常少于调用 func 时传入的参数个数。 当一个函数 func 可以接收很多参数,而某一次使用只需要更改其中的一部分参数,其他的某些参数都保持不变时, partial 对象就可以将这些不变的对象冻结起来,这样调用 partial 对象时传入未冻结的参数, partial 对象调用 func 时连同已经被冻结的参数一同传给 func 函数,从而简化了调用过程。

  如果调用 partial 对象时提供了更多的参数,那么他们会被添加到 args 的后面,如果提供了更多的关键字参数,那么它们将扩展或覆写已经冻结的关键字参数

   partial 对象的作用大抵如下:

def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc

  使用 partial 对象创建一个 base 参数始终为 2 的 int()

from functools import partial

basetwo = partial(int, base=2)
basetwo.__doc__ = 'Convert base 2 string to an int.'
basetwo('')

  这个新的 partial 对象 basetwo 能够将二进制的参数转化为十进制的整型结果,在调用这个 partial 对象时只需要传入二进制的目标参数即可。

5.

functools.update_wrapper(wrapper, wrapped[, assigned][, updated])

  更新一个包裹(wrapper)函数,使其看起来更像被包裹(wrapped)的函数。

  可选的参数指定了被包裹函数的哪些属性直接赋值给包裹函数的对应属性,同时包裹函数的哪些属性要更新而不是直接接受被包裹函数的对应属性。参数 assigned 的默认值对应于模块级常量 WRAPPER_ASSIGNMENTS (默认地将被包裹函数的 __name__, __module__ 和 __doc__ 属性赋给包裹函数), 参数 updatedd  的默认值对应于模块级常量 WRAPPER_UPDATES (默认更新 wrapper 函数的 __dict__ 属性)。

  这个函数的主要用途是在一个装饰器中,原函数会被装饰(包裹),装饰器函数会返回一个 wrapper 函数,如果装饰器返回的这个 wrapper 函数没有被更新,那么它的一些元数据更多的是反映 wrapper 函数定义时的特征,无法反映 wrapped 函数的特性。

6.

functools.wraps(wrapped[, assigned][, updated])

  这个函数可以用作一个装饰器,简化调用上一个函数 update_wrapper 的过程。调用这个函数等价于调用  partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)  。

  例如:

>>> from functools import wraps
>>> 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()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'

  可以看到最终调用的 example() 函数是经过 @my_decorator 装饰的,装饰器的作用是接受一个被包裹函数作为参数,对其进行加工,返回一个包裹函数。代码使用 @functools.wraps 装饰将要返回的包裹函数 wrapper,使得他的 __name__, __doc__ 和 __module__ 属性与被装饰函数 examle()完全相同, 这样虽然最终调用的是经过装饰的 example() 函数,但是某些属性还是得到了维护。

  如果在 @my_decorator 的定义中不使用 @functools.wraps 装饰包裹函数,那么最终 example.__name__ 将会变为 ‘wrapper’, 而 example.__doc__ 也会丢失。

partial对象

  partial对象是调用partial()时创建的可调用对象,他们有三个只读的属性:

1.  partial.func

  可调用或函数,调用partial对象时,会结合新的参数和关键字最终调用func。

2.  partial.args

  默认为最左的位置参数,这些参数会被自动添加到所有调用partial对象时传入的参数前。也就是说在调用partial对象时不用传入这些参数即可,他们视为恒定的,从而自动添加到func的调用中。

3.  partial.keywords

  当调用partial对象时提供的关键字参数。

  partial对象在一些方面类似于函数对象:可调用,弱引用,可以拥有属性。但是也有一些关键的区别:

  1.partial对象的 __name__ 和 __doc__ 属性不会自动创建;

  2. 在类里定义的partial对象使用时更像静态方法,在实例的属性查询过程中不会转变成绑定方法(bound methods, 通过类的实例对象进行属性引用)。

Python——functools的更多相关文章

  1. python functools.wraps functools.partial实例解析

    一:python functools.wraps 实例 1. 未使用wraps的实例 #!/usr/bin/env python # coding:utf-8 def logged(func): de ...

  2. python functools模块

    functools.partial 作用: functools.partial 通过包装手法,允许我们 "重新定义" 函数签名 用一些默认参数包装一个可调用对象,返回结果是可调用对 ...

  3. python functools.wraps装饰器模块

    # -*-coding=utf-8 -*-#实现一个函数执行后计算执行时间的功能 __author__ = 'piay' import time, functools def foo(): ''' 定 ...

  4. python functools

    # 工具函数import functools print(dir(functools)) # partial函数(偏函数)def showarg(*args,**kw): print(args) pr ...

  5. (转)Python——functools

    原文:https://www.cnblogs.com/Security-Darren/p/4168310.html#t7 http://www.wklken.me/posts/2013/08/18/p ...

  6. python functools.lru_cache做备忘功能

    import time import functools def clock(func): @functools.wraps(func)#还原被装饰函数的__name__和__doc__属性 def ...

  7. python functools.partial

    functools.partial 用一些默认参数包装一个可调用对象,返回结果是可调用对象,并且可以像原始对象一样对待 冻结部分函数位置函数或关键字参数,简化函数,更少更灵活的函数参数调用 refer ...

  8. python functools.wraps

    我们在使用装饰器的时候,有些函数的功能会丢失,比如func.__name__,func.__doc__,func.__module__ 比如下面这个例子: In [16]: def logged(fu ...

  9. python:functools之partial

    示例:from operator import addimport functoolsprint add(1,2) #3add1 = functools.partial(add,1)print add ...

随机推荐

  1. PYTHON学习之路_PYTHON基础(1)

    学习内容: 1.Python介绍 2.Python程序初接触和变量 3.Python用户交互 4.Python数据类型 5.Python循环if...(elif)...else 6.Python循环w ...

  2. 如何在MFC中创建非矩形button

    一般情况下,我们创建的按钮都是矩形的,但有时为了满足特殊的需求,我们要在对话框中创建一个非矩形的按钮,比如,圆形,椭圆等. 要实现一个非矩形的按钮,这就涉及到了自绘控件.自绘控件的方法有很多,可以参考 ...

  3. chardet坑——比蜗牛还慢

    需求 最近在做一个功能,使用python爬取网页然后保存到本地.其中遇到的一个难题是判断页面的编码方式.有问题就百度喽,当时我没想到自己去解决.一百度就找到了一个叫chardet的插件.大喜过望,试了 ...

  4. 【转】js写显示农历的日期

    网上查找了个,记录下. <body> <!-- 中国农历开始 --> <SCRIPT language=JavaScript> <!-- var lunarI ...

  5. Linux之RPM安装软件

    源码包 (可以看到源代码)      脚本安装包(写好的xsheel一键安装.本质还是源码包和二进制包) 二进制包(RPM包.系统默认包)      包管理系统简单,通过命令就可以安装.卸载     ...

  6. 微软Connect教程系列—VS2015集成新潮工具(四)

    本课程来源与微软connect视频教程,Modern Web Tooling in Visual Studio 2015 本课程主要讲下当下流行的前端工具 bower和grunt 首先简单介绍下这俩货 ...

  7. C#函数式编程之序列

    过了许久的时间,终于趁闲暇的时间来继续将函数式编程这个专辑连载下去,这段时间开头是为IOS这个新方向做准备,将OC的教程写成了SWIFT版,当然我个人是支持Xamarin,但是我一般会先掌握原生态的开 ...

  8. Quartz.net(调度框架) 使用Mysql作为存储

    最近公司的做的项目中涉及到配置任务地址然后按照配置去目标地址提取相关的数据,所以今天上午在Internet上查看有关定时任务(调度任务)的相关信息,筛选半天然后查找到Quartz.net. Quart ...

  9. 【腾讯Bugly干货分享】QFix探索之路—手Q热补丁轻量级方案

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ff5832bb8fec206ce2185d 导语 QFix 是手Q团队近期推 ...

  10. objective-c(类别)

    objective-c中的Categary(类别)使用相当广泛,其内涵类似于javascript中的prototype,可以扩展某一个类的方法. 下面给出一个基本的例子,参考oc程序设计一书: 实现一 ...