通常情况下我不会问这样的问题,但是python似乎有1.一个不同寻常的社区对习语的共识,并且倾向于通过使它们更高效来鼓励它们(例如列表理解与地图,过滤器)。 / p>
这是我在编码时发现自己使用的模式,请考虑以下JavaScript:
var f = (function() {
var closedOver = "whatever"
return function(param) {
// re-uses closure variable again and again with different param
}
})();
或C:
int foo(int x)
{
/*
compile-time constant, will not be recalced for every call,
name 'someConst' not visible in other scopes
*/
const int someConst = 134;
/* do stuff */
return whatever;
}
转换为python的一些可能方法:
globalConstant = someConstant
def foo(param):
# does stuff with param and constant
return whatever
或可能:
from functools import partial
def foo(invariant, variant):
"""Actually bar"""
# does stuff
return whatever
bar = partial(foo, someInvariant)
或:
class Foo(object):
"""I'm just here to hold a non-visible binding. Actually bar"""
def __init__(self, invariant):
super(Foo, self).__init__()
self.value = invariant
def __call__(self, param):
return actualFnResultWithSelfValue
bar = Foo(invariant)
或:
def foo(variant, invariant=someConstantValue):
return whatever
这很不幸,现在取决于我走哪条路,我可能不得不使用一个丢弃名称作为初始函数定义,因为我只使用部分应用的版本,编写了很多样板类(也是当它只在一个函数中使用时,或者使用全局常量污染模块命名空间,或者限制我的函数参数并确保有人可以通过使用错误数量的参数调用它来破坏它。
我也可以通过重新实例化每一个电话来解决这个问题,并希望它会被优化掉,但是因为我没有使用pypy,所以我不会对这个分数抱太大希望。
所以我的问题有两个方面:首先,有没有办法在没有权衡的情况下做到这一点?第二,如果没有,上面哪个是最“pythonic”(惯用的,高性的,合理的等)?
答案 0 :(得分:4)
这是我的经验法则:如有疑问,请尽量使用Python标准库。您对此functools.partial
的直觉是正确的,原因如下:
我希望有所帮助!
答案 1 :(得分:1)
我建议一些通常是代码味道的东西 - 默认的可变参数。
琐碎的例子:
def f(x, cache={'x': 0}):
cache['x'] += x;
return cache['x']
assert f(1) == 1
assert f(1) == 2
assert f(1) == 3
assert f(3) == 6
您的dict(或列表,或任何可变的)绑定到函数对象。当省略cache关键字参数时,后续调用将引用同一对象。此对象状态将在调用过程中持续存在。
答案 2 :(得分:0)
我不喜欢外部范围的var的想法,并且可能建议使用闭包,我认为这是更好的方式,因为你看它更像JavaScript,所以你可以使用函数作为对象:
def foo():
const = 1
def bar(param):
return const + param
return bar
a = foo()
print(a(5))
答案 3 :(得分:0)
有一个你没有提到的替代方案,这是IMO最不会产生扔掉名字的pythonic方式:)
def foo(variant):
try:
return foo.invariant + variant
except AttributeError:
foo.invariant = 1
return foo(variant)
虽然坚持使用std库是最好的。
答案 4 :(得分:0)
我不认为你的两个第一个例子是等价的。第一个似乎是闭包,而第二个使用全局常量。无论如何,对于第一个例子,python中的直接等价物将是
def f(x):
def g(y):
return x + y
return g
并像
一样使用它add2 = f(2)
print(add2(3)) # == 5
实际上,您使用partial
实现了类似的内容