python减少函数可调用对象的参数个数

问题
你有一个被其他python代码使用的callable对象,可能是一个回调函数或者是一个处理
器, 但是它的参数太多了,导致调用时出错。
解决方案
如果需要减少某个函数的参数个数,你可以使用 functools.partial() 。 partial() 函数
允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。 为了演示清
楚,假设你有下面这样的函数:

# encoding:utf-8
# usr/bin/python
def spam(a, b, c, d):
    print(a, b, c, d)

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

# encoding:utf-8
# usr/bin/python
from functools import partial


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


s1 = partial(spam, 1)  # a = 1
print s1(2, 3, 4)

print s1(4, 5, 6)

s2 = partial(spam, d=42)  # d = 42

print s2(1, 2, 3)

print s2(4, 5, 5)

s3 = partial(spam, 1, 2, d=42)  # a = 1, b = 2, d = 42

print s3(3)

print s3(4)

输出:

(1, 2, 3, 4)
(1, 4, 5, 6)
(1, 2, 3, 42)
(4, 5, 5, 42)
(1, 2, 3, 42)
(1, 2, 4, 42)

可以看出 partial() 固定某些参数并返回一个新的callable对象。这个新的callable接受未
赋值的参数, 然后跟之前已经赋值过的参数合并起来,最后将所有参数传递给原始函
数。
讨论
本节要解决的问题是让原本不兼容的代码可以一起工作。下面我会列举一系列的例子。
第一个例子是,假设你有一个点的列表来表示(x,y)坐标元组。 你可以使用下面的函数来计
算两点之间的距离:

# encoding:utf-8
# usr/bin/python
points = [(1, 2), (3, 4), (5, 6), (7, 8)]


def distance(p1, p2):
    x1, y1 = p1
    x2, y2 = p2
    return math.hypot(x2 - x1, y2 - y1)

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

pt = (4, 3)
points.sort(key=partial(distance,pt))
print points

输出:

[(3, 4), (1, 2), (5, 6), (7, 8)]

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

# encoding:utf-8
# usr/bin/python


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 + y


if __name__ == '__main__':
    import logging
    from multiprocessing import Pool
    from functools import partial

    logging.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 对这些一无所知——它仅仅只是使用单个值来调用回调函数。
 

转载于:https://my.oschina.net/yves175/blog/1568154

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值