Python:重新定义函数,使其引用自己的自身

时间:2018-09-16 22:40:15

标签: python python-3.x function reference functional-programming

说我有一些函数fun,其实际代码主体不在我的控制范围内。我可以创建一个新函数,该函数在调用fun之前进行一些预处理,即

def process(x):
    x += 1
    return fun(x)

如果我现在希望process代替fun来以后所有对fun的呼叫,我需要做类似的事情

# Does not work
fun = process

但是,这不起作用,因为这会产生一个循环引用问题,因为现在fun的主体内部已调用fun。我发现一种解决方案是在fun内引用process的副本,如下所示:

# Works
import copy
fun_cp = copy.copy(fun)
def process(x):
    x += 1
    return fun_cp(x)
fun = process

但是这个解决方案使我感到困扰,因为我真的不知道Python如何构造函数的副本。我猜我的问题与使用继承和super函数扩展类方法的问题相同,但是在这里我没有类。

如何正确执行此操作?我认为这是一项足够常见的任务,应该或多或少有一些惯用的解决方案,但是我没有运气找到它。

3 个答案:

答案 0 :(得分:1)

这看起来像是python闭包的用例。有一个函数返回您的函数。

android studio

答案 1 :(得分:1)

Python不是 构造函数的副本。 copy.copy(fun)仅返回fun;区别在于您将其保存到fun_cp变量中,该变量与您保存process的变量不同,因此当fun_cp尝试查找时,它仍在process中它。

我将执行与您所做的类似的操作,将原始函数保存到其他变量中,而无需添加“ copy”:

original_fun = fun
def fun(x):
    x += 1
    return original_fun(x)

如果要将相同的包装应用于多个功能,则定义装饰器并执行fun = decorate(fun)更可重用,但是一次性执行则比必要的工作更多,而且缩进程度更高。

答案 2 :(得分:0)

使用闭包的想法向Coldspeed致谢。一个完整的工作和完善的解决方案是

    %PDF-1.4
1 0 obj
<<
/Title (��)
/Creator (��)
/Producer (��Qt 5.5.1)
/CreationDate (D:20180916225804)
>>
endobj
2 0 obj
<<
/Type /Catalog
/Pages 3 0 R
>>
endobj
4 0 obj

请注意,这等同于将装饰器(import functools def getprocess(f): @functools.wraps(f) def process(x): x += 1 return f(x) return process fun = getprocess(fun) )应用于getprocess 100%。我无法提出这种解决方案,因为专用装饰器语法fun仅可在函数的定义位置(此处为@getprocess)使用。要将其应用于现有功能,只需执行fun