functools模块处理的对象都是其他的函数,任何可调用对象都可以被视为用于此模块的函数。

1. functools.cmp_to_key(func)
因为Python3不支持比较函数,cmp_to_key就是将老式的比较函数(comparison function)转换成关键字函数(key function),与能够接受key function的函数一起使用,比如说sorted,list.sort, min, max, heapq.nlargest, itertools.groupby等等。

例子:

    from functools import cmp_to_key
def compare(x1, x2):
return x1 - x2 a = [2, 3, 1]
print(sorted(a, key=cmp_to_key(compare)))
a.sort(key=cmp_to_key(compare))
print(a)

输出:

[1, 2, 3]
[1, 2, 3]

 

2. @functools.lru_cache(maxsize=128, typed=False)
lru_cache可以作为装饰器将函数计算耗时的结果缓存起来,用来节省时间。
由于是使用字典进行的缓存,因此函数的关键字参数和位置参数必须是可哈希的。
如果maxsize=None,禁用lru功能,并且缓存可以无限制的增长。
当maxsize为2的幂次方时,lru的性能最好。

如果将typed设置为true,将单独缓存不同类型的函数参数,比如F(3)和F(3.0)将被视为不同结果的不同调用。

cache_info()函数可以用来测量缓存的有效性和优化maxsize参数。该函数返回一个命中、未命中、maxSize和currSize的命名的元组。
例子:

    from functools import lru_cache

    @lru_cache(maxsize=32)
def get_pep(num):
resource = "http://www.python.org/dev/peps/pep-%04d/" % num
try:
with urllib.request.urlopen(resource) as s:
return s.read()
except urllib.error.HTTPError:
return "Not Found" for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
pep = get_pep(n)
print(n, len(pep)) print(get_pep.cache_info()) @lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n - 2) print([fib(n) for n in range(16)])
print(fib.cache_info())

  

3. @functools.total_ordering
指定一个已经定义了一个或者多个比较排序方法的类,这个类修饰器提供其余的方法。
这个类必须已经定义了__lt__(), __le__(), __gt__(), __ge__()中的一个,并且定义了__eq__()

    from functools import total_ordering

    @total_ordering
class Student: def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name @staticmethod
def _is_valid_operand(other):
return hasattr(other, "last_name") and hasattr(other, "first_name") def __eq__(self, other):
if not self._is_valid_operand(other):
return NotImplemented
return ((self.last_name.lower(), self.first_name.lower()) ==
(other.last_name.lower(), other.first_name.lower())) def __lt__(self, other):
if not self._is_valid_operand(other):
return NotImplemented
return ((self.last_name.lower(), self.first_name.lower()) <
(other.last_name.lower(), other.first_name.lower())) a = Student(first_name="tom", last_name="hancs")
b = Student(first_name="tom", last_name="hancs")
print(a == b)
print(a <= b)
print(a >= b)

  

如果不使用total_ordering对装饰器进行装饰的话,使用<=或者>=会报错:

Traceback (most recent call last):
File "D:/LearnProject/performance/functools_test.py", line 33, in <module>
print(a <= b)
TypeError: '<=' not supported between instances of 'Student' and 'Student'

4. functools.partial(func, *args, **keywords)
partial()用于冻结函数参数或者关键的其中一部分,生成一个简化了参数传入的新的函数对象。
例子:

from functools import partial

basetwo = partial(int, base=2)
print(basetwo('111'))

5. functools.partialmethod(func, *args, **keywords)
功能与partial类似,用法如下:

    from functools import partialmethod

    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)

  

6. reduce(function, iterable[,initializer])
将两个参数的函数从左到右累计应用于序列项,比如reduce(lambda x, y:x+y, [1, 2, 3, 4, 5]),相当于计算(((1+2)+3)+4)+5。

    from functools import reduce
print(reduce(lambda x, y: x+y, range(0, 10)))

  

7. @functools.singledispatch
当有一个函数需要根据传入的变量的类型来判断需要输出的内容时,通常的做法是在函数内部使用大量的if/elif/else来解决问题。
这样做会使代码显得笨重,难以维护,也不便于扩展。
functools.singledispatch方法就是用于处理这个问题的

用法:

    from functools import singledispatch

    @singledispatch
def func(arg, verbose=False):
if verbose:
print("Let me just say,", end=" ")
print(arg) @func.register(int)
def _(arg, verbose=False):
if verbose:
print("Strength in numbers, eh?", end=" ")
print(arg) @func.register(list)
def _(arg, verbose=False):
if verbose:
print("Enumerate this:")
for i, elem in enumerate(arg):
print(i, elem) def nothing(arg, verbose=False):
print("Nothing.") func.register(type(None), nothing) @func.register(float)
def fun_num(arg, verbose=False):
if verbose:
print("Half of your number:", end=" ")
print(arg / 2) func("Hello, world.")
func("test.", verbose=True)
func(42, verbose=True)
func(["spam", "spam", "eggs", "spam"], verbose=True)
func(None)
func(1.23) # 检查泛型函数将为给定类型选择哪个实现
print(func.dispatch(float))
print(func.dispatch(dict)) # 访问所有已经注册的实现
print(func.registry.keys())
print(func.registry[float])

  

8. functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
用来更新被装饰函数的__name__,__doc__等信息,使其看起来像被装饰的函数

    from functools import update_wrapper

    def wrap(func):
def call_it(*args, **kwargs):
"""call it"""
return func(*args, **kwargs)
return call_it @wrap
def hello():
"""say hello"""
print("hello world") def wrap2(func):
def call_it2(*args, **kwargs):
"""call it2"""
return func(*args, **kwargs)
return update_wrapper(call_it2, func) @wrap2
def hello2():
"""say hello2"""
print("hello world2") print(hello.__name__)
print(hello.__doc__) print(hello2.__name__)
print(hello2.__doc__)

  

9. @functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
使用了wraps的装饰器可以保留被装饰函数的属性

    from functools import wraps

    def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
print("Calling decorated function")
return f(*args, **kwargs)
return wrapper @my_decorator
def example():
"""Example Docstring"""
print("Called example function") example()
print(example.__name__)
print(example.__doc__)

  

文章中的例子来自Python官方文档和网络。

Python标准库: functools (cmp_to_key, lru_cache, total_ordering, partial, partialmethod, reduce, singledispatch, update_wrapper, wraps)的更多相关文章

  1. python标准库--functools.partial

        官方相关地址:https://docs.python.org/3.6/library/functools.html 一.简单介绍: functools模块用于高阶函数:作用于或返回其他函数的函 ...

  2. Python标准库笔记(9) — functools模块

    functools 作用于函数的函数 functools 模块提供用于调整或扩展函数和其他可调用对象的工具,而无需完全重写它们. 装饰器 partial 类是 functools 模块提供的主要工具, ...

  3. 转--Python标准库之一句话概括

    作者原文链接 想掌握Python标准库,读它的官方文档很重要.本文并非此文档的复制版,而是对每一个库的一句话概括以及它的主要函数,由此用什么库心里就会有数了. 文本处理 string: 提供了字符集: ...

  4. Python 标准库中的装饰器

    题目描述 1.简单举例 Python 标准库中的装饰器 2.说说你用过的 Python 标准库中的装饰器 1. 首先,我们比较熟悉,也是比较常用的 Python 标准库提供的装饰器有:property ...

  5. Python标准库笔记(10) — itertools模块

    itertools 用于更高效地创建迭代器的函数工具. itertools 提供的功能受Clojure,Haskell,APL和SML等函数式编程语言的类似功能的启发.它们的目的是快速有效地使用内存, ...

  6. python第六天 函数 python标准库实例大全

    今天学习第一模块的最后一课课程--函数: python的第一个函数: 1 def func1(): 2 print('第一个函数') 3 return 0 4 func1() 1 同时返回多种类型时, ...

  7. Python 标准库一览(Python进阶学习)

    转自:http://blog.csdn.net/jurbo/article/details/52334345 写这个的起因是,还是因为在做Python challenge的时候,有的时候想解决问题,连 ...

  8. python 标准库大全

    python 标准库 文本 string:通用字符串操作 re:正则表达式操作 difflib:差异计算工具 textwrap:文本填充 unicodedata:Unicode字符数据库 string ...

  9. Python标准库14 数据库 (sqlite3)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Python自带一个轻量级的关系型数据库SQLite.这一数据库使用SQL语言.S ...

随机推荐

  1. 如何使用ArcGIS Pro发布自定义打印服务

    我们知道可以通过ArcGIS Map来发布自定义打印服务.从ArcGIS Enterprise 10.6.1版本起,打印服务的功能更加完善了,改进点包括: 支持打印矢量切片服务 改进了智能制图和颜色透 ...

  2. 消息队列Rabbit MQ 学习第一篇

    1 介绍  1.1RabbitMQ MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队 ...

  3. Linux远程传输文件免密码

    首先为什么Linux远程传输要免密码?手动使用scp命令传输每次都要输密码太过麻烦了. 开发中有一句话,能复制粘贴尽量不要手打. 运维中有一句话,能脚本化实现尽量不要手动执行. 远程传输文件免密码的目 ...

  4. UDP如何实现可靠传输

    概述 UDP不属于连接协议,具有资源消耗少,处理速度快的优点,所以通常音频,视频和普通数据在传送时,使用UDP较多,因为即使丢失少量的包,也不会对接受结果产生较大的影响. 传输层无法保证数据的可靠传输 ...

  5. Django 创建数据库表

    1.连接数据库之前,我们需要在setting中修改一些内容 2.Django的表是在models中创建的,一个class代表一个数据库表 abstract是为了继承,将该基类定义为抽象类,即不必生成数 ...

  6. Open vSwitch系列实验(三):Open vSwitch的VxLAN隧道网络实验

    1 实验目的 该实验通过Open vSwitch构建Overlay的VxLAN网络,更直观的展现VxLAN的优势.在实验过程中,可以了解如何建立VxLAN隧道并进行配置,并实现相同网段和不同网段之间的 ...

  7. Tomcat 管理监控工具

    本文链接:https://blog.csdn.net/weixin_34364071/article/details/86753232 专注于Java领域优质技术号,欢迎关注 原创: 侯树成 Tomc ...

  8. ASP.NET_微信JS_SDK调用

    using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;usi ...

  9. nginx: [emerg] unknown directive "stub_status" in /home/oscf/nginx/conf/conf.d/ngx_metric.conf

    解压安装过程命令如下: cd /home/oscf #该目录下有nginx压缩包 mkdir nginx tar -zxvf nginx-1.16.0.tar.gz cd nginx-1.16.0 . ...

  10. JEECG hibernate.hbm2ddl.auto

    配置hibernate根据实体类自动建表功能 - lixuyuan的专栏 - CSDN博客https://blog.csdn.net/lixuyuan/article/details/8057119 ...