[英]What is the most pythonic way to apply a function on and return multiple columns?
[英]What is the most pythonic way to reuse data in multiple calls to same function?
通常我不会问这样的问题,但是python似乎有1.一个不同寻常的社区对习语的共识,并且通过使它们更具性能来鼓励它们(例如列表理解与地图,过滤器)。
这是我在编码时发现自己使用的模式,请考虑以下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”(惯用,高性能,合理等)?
贾里德,我完全明白你犹豫要问这个,因为它可以通过许多不同的意见来回答,并产生一场火焰战争。 但是,我同意你的看法:随着时间的推移,Python社区确实倾向于与许多实现问题保持一致。 这是Python的优势之一。
这是我的经验法则:如有疑问,请尽量使用Python标准库。 你对functools.partial
直觉是正确的,原因如下:
我希望有所帮助!
我建议一些通常是代码气味的东西 - 默认的可变参数。
琐碎的例子:
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关键字参数时,后续调用将引用同一对象。 此对象状态将在调用之间保持不变。
我不喜欢外部范围的var的想法,可能建议使用闭包,我认为这是更好的方式,因为你看它更像JavaScript,所以你可以使用函数作为对象:
def foo():
const = 1
def bar(param):
return const + param
return bar
a = foo()
print(a(5))
还有一个你没有提到的替代方案,这是IMO最狡猾的方式,它不会创造一个扔掉的名字:)
def foo(variant):
try:
return foo.invariant + variant
except AttributeError:
foo.invariant = 1
return foo(variant)
虽然坚持使用std库是最好的。
我不认为你的两个第一个例子是等价的。 第一个似乎是闭包,而第二个使用全局常量。 无论如何,对于第一个例子,python中的直接等价物将是
def f(x):
def g(y):
return x + y
return g
并使用它
add2 = f(2)
print(add2(3)) # == 5
实际上,你的实现使用partial
,在引擎盖下做了类似的事情
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.