在多次调用同一函数时重用数据的最pythonic方法是什么?

Jar*_*ith 7 python

通常我不会问这样的问题,但是python似乎有1.一个不同寻常的社区对习语的共识,并且倾向于通过使它们更高效来鼓励它们(例如列表理解对比地图,过滤器).

这是我在编码时发现自己使用的模式,请考虑以下JavaScript:

var f = (function() {
  var closedOver = "whatever"
  return function(param) {
    // re-uses closure variable again and again with different param
  }
})();
Run Code Online (Sandbox Code Playgroud)

或者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;
}
Run Code Online (Sandbox Code Playgroud)

一些可能的方法转换为python:

globalConstant = someConstant
def foo(param):
    # does stuff with param and constant
    return whatever
Run Code Online (Sandbox Code Playgroud)

或者可能:

from functools import partial
def foo(invariant, variant):
    """Actually bar"""
    # does stuff
    return whatever

bar = partial(foo, someInvariant)
Run Code Online (Sandbox Code Playgroud)

要么:

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)
Run Code Online (Sandbox Code Playgroud)

要么:

def foo(variant, invariant=someConstantValue):
  return whatever
Run Code Online (Sandbox Code Playgroud)

这是不幸的,现在取决于我走哪条路我可能不得不使用一个丢弃的名称作为初始函数定义,因为我只使用部分应用的版本,写了很多样板类(也有抛出 - 当它仅在一个函数中使用时,或者使用全局常量污染模块命名空间,或限制我的函数参数并确保有人可以通过使用错误数量的参数调用它来破坏它.

我也可以通过重新实例化每次通话来"解决"这个问题,并希望它会被优化掉,但由于我没有使用pypy,我对这个得分并不太有希望.

所以我的问题有两个方面:首先,有没有办法在没有权衡的情况下做到这一点?第二,如果没有,上面哪个是最"pythonic"(惯用,高性能,合理等)?

Łuk*_*ski 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
Run Code Online (Sandbox Code Playgroud)

你的字典(或列表,或任何可变的东西)绑定到函数对象。当省略 cache 关键字参数时,后续调用将引用同一对象。该对象状态将在调用期间持续存在。