[英]Python: Redefine function so that it references its own self
說我有一些fun
的功能,實際的代碼主體不在我的控制范圍內。 我可以創建一個新函數,在調用fun
之前進行一些預處理,即
def process(x):
x += 1
return fun(x)
如果現在我希望在以后所有的fun
調用中都用process
代替fun
,我需要做一些類似的事情
# Does not work
fun = process
然而,這並不工作,因為這會產生像現在一個循環引用問題fun
是從身體內稱為fun
。 我發現的一種解決方案是在process
內引用fun
的副本,如下所示:
# Works
import copy
fun_cp = copy.copy(fun)
def process(x):
x += 1
return fun_cp(x)
fun = process
但是這種解決方案使我感到困擾,因為我並不真正了解Python如何構造函數的副本。 我猜我的問題與使用繼承和super
函數擴展類方法的問題相同,但是在這里我沒有類。
如何正確執行此操作? 我認為這是一項足夠常見的任務,應該或多或少有一些慣用的解決方案,但是我沒有運氣找到它。
這看起來像是python閉包的用例。 有一個函數返回您的函數。
def getprocess(f):
def process(x):
x += 1
return f(x) # f is referenced from the enclosing scope.
return process
myprocess = getprocess(fun)
myprocess = getprocess(myprocess)
Python 沒有構造函數的副本。 copy.copy(fun)
只是返回fun
; 區別在於您將其保存到fun_cp
變量,該變量與您將process
保存到的變量不同,因此當process
嘗試查找該fun_cp
時,它仍在fun_cp
process
。
我將執行與您所做的類似的操作,將原始函數保存到其他變量中,而無需“復制”:
original_fun = fun
def fun(x):
x += 1
return original_fun(x)
如果要對多個函數應用相同的包裝,則定義裝飾器並執行fun = decorate(fun)
更可重用,但是一次性而言,它比必要的工作更多,而且縮進程度更高。
感謝Coldspeed提出使用閉包的想法。 一個完整的工作和完善的解決方案是
import functools
def getprocess(f):
@functools.wraps(f)
def process(x):
x += 1
return f(x)
return process
fun = getprocess(fun)
請注意,這等同於將裝飾器( getprocess
)應用於fun
。 我無法提出這個解決方案,因為專用的裝飾器語法@getprocess
只能在函數的定義位置(此處為fun
)使用。 要將其應用於現有函數,只需執行fun = getprocess(fun)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.