目录

1、典型应用

2、问题引入

3、举例-计算两点距离排序

4、微调回调函数


声明:文章仅作知识整理、分享,如有侵权请联系作者删除博文,谢谢!

1、典型应用

典型的,函数在执行时,要带上所有必要的参数进行调用。然后,有时参数可以在函数被调用之前提前获知。这种情况下,一个函数有一个或多个参数预先就能用上,以便函数能用更少的参数进行调用。

import functoolsdef add(a, b):return a + b
add(4, 2)
6plus3 = functools.partial(add, 3)
plus5 = functools.partial(add, 5)
plus3(4)
7
plus3(7)
10
plus5(10)
15

2、问题引入

你有一个被其他python代码使用的callable对象,可能是一个回调函数或者是一个处理器, 但是它的参数太多了,导致调用时出错。

解决方案:

如果需要减少某个函数的参数个数,你可以使用 functools.partial() 。 partial() 函数允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。 为了演示清楚,假设你有下面这样的函数:

def spam(a, b, c, d):print(a, b, c, d)

现在我们使用 partial() 函数来固定某些参数值:

>>> from functools import partial
>>> s1 = partial(spam, 1) # a = 1
>>> s1(2, 3, 4)
1 2 3 4
>>> s1(4, 5, 6)
1 4 5 6
>>> s2 = partial(spam, d=42) # d = 42
>>> s2(1, 2, 3)
1 2 3 42
>>> s2(4, 5, 5)
4 5 5 42
>>> s3 = partial(spam, 1, 2, d=42) # a = 1, b = 2, d = 42
>>> s3(3)
1 2 3 42
>>> s3(4)
1 2 4 42
>>> s3(5)
1 2 5 42

可以看出 partial() 固定某些参数并返回一个新的callable对象。这个新的callable接受未赋值的参数, 然后跟之前已经赋值过的参数合并起来,最后将所有参数传递给原始函数。

3、举例-计算两点距离排序

本节要解决的问题是让原本不兼容的代码可以一起工作。下面我会列举一系列的例子。

第一个例子是,假设你有一个点的列表来表示(x,y)坐标元组。 你可以使用下面的函数来计算两点之间的距离:

points = [ (1, 2), (3, 4), (5, 6), (7, 8) ]
import math
def distance(p1, p2):x1, y1 = p1x2, y2 = p2return math.hypot(x2 - x1, y2 - y1)

说明一下这里的math.hypot默认是以坐标原点为几点计算坐标到原点的直线距离:

import math
print(math.hypot(6,8))
>>>10

现在假设你想以某个点为基点,根据点和基点之间的距离来排序所有的这些点。 列表的 sort() 方法接受一个关键字参数来自定义排序逻辑, 但是它只能接受一个单个参数的函数(distance()很明显是不符合条件的)。 现在我们可以通过使用 partial() 来解决这个问题:

>>> pt = (4, 3)
>>> points.sort(key=partial(distance,pt))
>>> points
[(3, 4), (1, 2), (5, 6), (7, 8)]
>>>

4、微调回调函数

更进一步,partial() 通常被用来微调其他库函数所使用的回调函数的参数。 例如,下面是一段代码,使用 multiprocessing 来异步计算一个结果值, 然后这个值被传递给一个接受一个result值和一个可选logging参数的回调函数:

def output_result(result, log=None):if log is not None:log.debug('Got: %r', result)# A sample function
def add(x, y):return x + yif __name__ == '__main__':import loggingfrom multiprocessing import Poolfrom functools import partiallogging.basicConfig(level=logging.DEBUG)log = logging.getLogger('test')p = Pool()p.apply_async(add, (3, 4), callback=partial(output_result, log=log))p.close()p.join()

当给 apply_async() 提供回调函数时,通过使用 partial() 传递额外的 logging 参数。 而 multiprocessing 对这些一无所知——它仅仅只是使用单个值来调用回调函数。

作为一个类似的例子,考虑下编写网络服务器的问题,socketserver 模块让它变得很容易。 下面是个简单的echo服务器:

from socketserver import StreamRequestHandler, TCPServerclass EchoHandler(StreamRequestHandler):def handle(self):for line in self.rfile:self.wfile.write(b'GOT:' + line)serv = TCPServer(('', 15000), EchoHandler)
serv.serve_forever()

不过,假设你想给EchoHandler增加一个可以接受其他配置选项的 __init__ 方法。比如:

class EchoHandler(StreamRequestHandler):# ack is added keyword-only argument. *args, **kwargs are# any normal parameters supplied (which are passed on)def __init__(self, *args, ack, **kwargs):self.ack = acksuper().__init__(*args, **kwargs)def handle(self):for line in self.rfile:self.wfile.write(self.ack + line)

这么修改后,我们就不需要显式地在TCPServer类中添加前缀了。 但是你再次运行程序后会报类似下面的错误:

Exception happened during processing of request from ('127.0.0.1', 59834)
Traceback (most recent call last):
...
TypeError: __init__() missing 1 required keyword-only argument: 'ack'

初看起来好像很难修正这个错误,除了修改 socketserver 模块源代码或者使用某些奇怪的方法之外。 但是,如果使用 partial() 就能很轻松的解决——给它传递 ack 参数的值来初始化即可,如下:

from functools import partial
serv = TCPServer(('', 15000), partial(EchoHandler, ack=b'RECEIVED:'))
serv.serve_forever()

在这个例子中,__init__() 方法中的ack参数声明方式看上去很有趣,其实就是声明ack为一个强制关键字参数。 关于强制关键字参数问题我们在7.2小节我们已经讨论过了,读者可以再去回顾一下。

很多时候 partial() 能实现的效果,lambda表达式也能实现。比如,之前的几个例子可以使用下面这样的表达式:

points.sort(key=lambda p: distance(pt, p))
p.apply_async(add, (3, 4), callback=lambda result: output_result(result,log))
serv = TCPServer(('', 15000),lambda *args, **kwargs: EchoHandler(*args, ack=b'RECEIVED:', **kwargs))

这样写也能实现同样的效果,不过相比而已会显得比较臃肿,对于阅读代码的人来讲也更加难懂。 这时候使用 partial() 可以更加直观的表达你的意图(给某些参数预先赋值)。

python functools下的partial模块应用相关推荐

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

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

  2. python下的mysql模块包装

    #!/usr/bin/env python # -*- coding: utf-8 -*-""" 设计db模块的原因:1. 更简单的操作数据库一次数据访问: 数据库连接 ...

  3. Python下使用tarfile模块来实现文件归档压缩与解压

    Python下使用tarfile模块来实现文件归档压缩与解压   部分转自:http://www.diybl.com/course/3_program/python/20110510/555345.h ...

  4. windows10在python环境下pip install安装模块方法(matplotlib、scipy、Pillow)

    windows10在python环境下pip install安装模块的方法: 1.准备工作:进入cmd窗口,输入python,检查python环境是否配置成功. 2.(退出python,)输入pyth ...

  5. Windows下python使用twine包发布模块

    本文讲解如何在Windows下,python使用twine包发布模块. 分享是美德 大Python有个模块发布功能,模板其实就是一个或多个函数打包的集合,当你写完一个函数,保存为.py文件后,可以进行 ...

  6. python中glob模块怎么下_如何在Python中使用glob.glob模块搜索子文件夹?

    如何在Python中使用glob.glob模块搜索子文件夹? 我想在文件夹中打开一系列子文件夹,找到一些文本文件并打印一些文本文件行. 我用这个: configfiles = glob.glob('C ...

  7. 在Windows环境下为Python 2.5安装SSL模块

    最近在捣腾Python,主要是因为Google App Engine比较诱人. 用官方的SDK,一开始装的是2.6,然后每次都会有很多提示deprecated,发现2.6对2.5的更新比较大,而且貌似 ...

  8. python导入机制及importlib模块

    文章目录 写在篇前 import 关键字 先导概念 namespace & scope Module & Packages module packages regular packag ...

  9. Python中的类、模块和包究竟是什么?

    Python培训教程:Python中的类.模块和包究竟是什么?在Python和其他编程语言中,都有类似或相同的概念,如对象.类.模块.包,名称都是一样的,只不过会有细微的一些区别,正是因为有这些存在, ...

最新文章

  1. opencv python cv2.threshold()函数报错 TypeError: Expected cv::UMat for argument 'mat'
  2. mt.exe : general error c101008d: Failed to write the updated manifest to the resource of file 原因调查
  3. linux修复u盘文件系统,linux下转换U盘文件系统
  4. C/C++ 存储类型 作用域 连接类型
  5. 服务器端可控情形的Javascript跨域访问解决方法
  6. Improving Opencv 1:The Core Functionality (core module) Mat - The Basic Image Container
  7. 版本控制工具--CVS
  8. 饿了么美团外卖源码php_从零搭建外卖CPS平台小程序开发
  9. 情感在语文教育中的作用
  10. opengl导入3DS文件(带纹理)之填坑
  11. 高手支招:免费拥有QQ魔法表情(转)
  12. 常见笔顺错误的字_常用汉字中易写错笔顺的字有哪些?
  13. 在局域网内主动封堵BT下载使用
  14. 通过js点击事件处理防止表单重复提交
  15. 数据传输方式串行快于并行
  16. 水星MW150US完美驱动10.6.X
  17. HTML5期末大作业:校园网站设计——云南艺术学院文化学院(3页) HTML+CSS+JavaScript web前端开发技术 web课程设计 网页规划与设计
  18. 16位浮点数(FP16)
  19. XGBoost的目标函数推导和分裂增益计算
  20. 微信小程序电商实战-入门篇

热门文章

  1. vue的动态组件和v-for结合实现按数据动态加载模板
  2. 数据库原理的基本概念
  3. 一键重装系统win7方法分享
  4. 如何查看自己电脑的windows系统版本?
  5. NEC成功完成对Avaloq的收购
  6. 乌拉!俄罗斯解禁盗版资源网,这波“报复”太疯狂
  7. 独立完成系统开发七:安全管理之鉴权
  8. 香港美酒佳肴巡礼首次于云端举行带游客领略舌尖上的饕餮盛宴
  9. python词云库wordcloud自定义词云制作步骤详解
  10. 计算机组成原理试题(五)(附参考答案)