簡體   English   中英

Python:重新定義函數,使其引用自己的自身

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM