一個相當有效的方法是使用functools.partial
,但正如已經指出的,partial
只允許你「凍結」最終的參數。如果您需要其他的東西,您可以使用closure輕鬆實現您自己的版本。
這種做法實際上是比使用partial
對象,有點更高效,當你調用它仍然叫你通過在原有的功能,所以每兩個呼叫partial
結果的通話partial
以來,和Python函數/方法調用相對較慢。如果你很好奇,看看the Python source code for functools.partial
。
在這個例子中,我將A
作爲函數的第二個(僞)參數,因爲partial
很好地處理了它是最後一個參數的情況。
def my_partial(param):
A = param
print('Creating two_arg_func with A ==', A)
def two_arg_func(t, y):
# Do something with all the args
return 'args', t, A, y
return two_arg_func
def test(f):
for u in range(10, 50, 10):
print(f(u, u + 5))
test(my_partial(7))
輸出
Creating two_arg_func with A == 7
('args', 10, 7, 15)
('args', 20, 7, 25)
('args', 30, 7, 35)
('args', 40, 7, 45)
我們並不真正需要my_partial
param
,我們可以只使用ARG傳遞,因爲這是本地my_partial
:
def my_partial(A):
print('Creating two_arg_func with A ==', A)
def two_arg_func(t, y):
return 'args', t, A, y
return two_arg_func
從您的意見,我現在明白,你想能夠改變A
。當然,您可以通過再次撥打partial
或my_partial
來完成此操作,但是如果您想修改A
,那麼效果不佳。
您的意見表明您想要在全球範圍內修改A
,所以您不妨使用全局。您不需要將代碼修改爲A
到全局上下文中,您可以將其包裝在一個函數中,但當然將需要在修改A
的函數中使用global
指令。不過,您需要而不是需要指令global
,它只讀取A
的值。
這是一個簡短的演示。
def two_arg_func(t, y):
# Do something with the args and with A
return 'args', t, A, y
def solve(f):
for u in range(10, 40, 10):
print('SOLVER', f(u, u + 5))
def test(f):
global A
for A in range(7, 10):
print(A)
solve(f)
test(two_arg_func)
輸出
7
SOLVER ('args', 10, 7, 15)
SOLVER ('args', 20, 7, 25)
SOLVER ('args', 30, 7, 35)
8
SOLVER ('args', 10, 8, 15)
SOLVER ('args', 20, 8, 25)
SOLVER ('args', 30, 8, 35)
9
SOLVER ('args', 10, 9, 15)
SOLVER ('args', 20, 9, 25)
SOLVER ('args', 30, 9, 35)
然而,以前的解決方案是有點不滿意,因爲你的問題的主旨是如何使用全局爲此沒有。所以這裏有一些代碼的細微變化。我們不把A
放在全局名稱空間中,而是將它作爲函數屬性附加到two_arg_func
。我們可以這樣做,因爲Python函數是一個對象,並且它已經有很多屬性;兩個你可能熟悉的是__name__
和__doc__
。無論如何,這是新代碼,它打印出與以前版本相同的輸出。
def two_arg_func(t, y):
A = two_arg_func.A
# Do something with the args and with A
return 'args', t, A, y
def solve(f):
for u in range(10, 40, 10):
print('SOLVER', f(u, u + 5))
def test(f):
for A in range(7, 10):
print(A)
f.A = A
solve(f)
test(two_arg_func)
還有'functools.partial' –
有沒有必要避免像鼠疫lambdas。也就是說,'def'可以做任何'lambda';你只是忘了'返回'的價值。 'functools.partial'也可以工作,儘管它不能修正前面不存在的位置參數。 – user2357112
Guido對'lambda'的主要反對意見是當人們用它來包裝一個簡單的表達式來傳遞給map(或filter)而不是直接在列表comp或gen exp中執行表達式,例如'map(lambda x :5 * x + 1,seq)'vs'(5 * x + 1 for x in seq)''。請注意,'map'version會引發'seq'中每個項目的Python函數調用的開銷。當然,如果傳遞給'map'的可調用函數在C中實現,例如'map(int,list_of_strings)'完全沒問題,那麼這是無關緊要的。 –