![](/img/trans.png)
[英]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.