python - 在 Python 中部分应用的高效方法?

标签 python lambda partial-application

我正在寻找一种在 python 中部分应用函数的方法,该方法易于理解、可读、可重用,并且尽可能减少编码人员出错的可能性。最重要的是,我希望样式尽可能高效——堆栈上的帧越少越好,部分应用函数的内存占用也越少也是可取的。我考虑了 4 种风格,并在下面写了例子:

import functools

def multiplier(m):
    def inner(x):
        return m * x

    return inner

def divide(n,d):
    return n/d

def divider(d):
    return functools.partial(divide,d=d)

times2 = multiplier(2)
print(times2(3))  # 6

by2 = divider(2)
print(by2(6)) # 3.0

by3 = functools.partial(divide,d=3)
print(by3(9)) # 3.0

by4 = lambda n: divide(n,4)
print(by4(12)) # 3.0

我对它们的分析是:

times2 是一个嵌套的东西。我想 python 用 m 绑定(bind)关闭,一切都很好。代码可读(我认为)并且易于理解。没有外部库。这是我今天使用的样式。

by2 有一个明确命名的函数,这对用户来说很简单。它使用 functools,所以它给你额外的导入。我在某种程度上喜欢这种风格,因为它是透明的,如果我愿意,可以选择以其他方式使用divide。将此与无法访问的 inner 进行对比。

by3 类似于 by2,但是强制代码的读者适应 functools.partial因为他们就在脸上。我不太喜欢的是 PyCharm 不能给我的工具提示告诉我 functools.partial 的参数应该是什么,因为它们实际上是 by3 的参数。每次定义一些新的部分应用程序时,我都必须自己知道 divide 的签名。

by4 易于输入,因为我可以获得自动完成功能。它不需要导入 functools。我认为它看起来不是pythonic。此外,我总是对在 python 中使用 lambda 工作的变量/闭包的范围界定感到不舒服。永远不确定那是如何表现的....

样式之间的逻辑区别是什么?这对内存和 CPU 有何影响?

最佳答案

第一种方式似乎是最有效的。我调整了您的代码,以便所有 4 个函数计算完全相同的数学函数:

import functools,timeit

def multiplier(m):
    def inner(x):
        return m * x

    return inner

def mult(x,m):
    return m*x

def multer(m):
    return functools.partial(mult,m=m)

f1 = multiplier(2)
f2 = multer(2)
f3 = functools.partial(mult,m=2)
f4 = lambda x: mult(x,2)

print(timeit.timeit('f1(10)',setup = 'from __main__ import f1'))
print(timeit.timeit('f2(10)',setup = 'from __main__ import f2'))
print(timeit.timeit('f3(10)',setup = 'from __main__ import f3'))
print(timeit.timeit('f4(10)',setup = 'from __main__ import f4'))

典型输出(在我的机器上):

0.08207898699999999
0.19439769299999998
0.20093803199999993
0.1442435820000001

这两种 functools.partial 方法是相同的(因为其中一个只是另一个的包装器),第一个快两倍,最后一个介于两者之间(但更接近首先)。在简单的闭包上使用 functools 有明显的开销。由于闭包方法可以说也更具可读性(并且比不能很好地扩展到更复杂函数的 lambda 更灵活),我会接受它。

关于python - 在 Python 中部分应用的高效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57822851/

相关文章:

python - VideoWriter 输出到 Google Cloud Storage

HTTParty 的 Python 等价物

c# - 如何从 List<T> 中检索项目,其中一个属性恰好包含另一个列表中的单词?

c# - IQueryable<T>.Where() 适合表达式在哪里?

javascript - 带有绑定(bind)的部分函数

python - SciKit Learn 并行处理 0.17 到 0.18 (Python 2.7)

c++ - 什么时候初始化 lambda 捕获?

JavaScript 和柯里化(Currying)

python - 动态添加内置方法以指向属性的内置方法

python - spark函数中approxCountDsitinct和approx_count_distinct的区别