代码之家  ›  专栏  ›  技术社区  ›  jmd_dk

Python:重新定义函数以便它引用自己的函数

  •  1
  • jmd_dk  · 技术社区  · 6 年前

    fun ,它的实际代码体超出了我的控制。我可以创建一个新函数,在调用之前进行一些预处理 ,即。

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

    如果我现在想 process 乐趣 以后打给 乐趣

    # Does not work
    fun = process
    

    但是,这不起作用,因为这会像现在一样产生循环引用问题 乐趣 从身体内部被召唤 乐趣 内部 ,就像这样:

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

    super 函数,但这里我没有课。

    我怎样才能做到这一点?我认为这是一个非常常见的任务,应该有一些或多或少惯用的解决方案,但我没有找到它。

    3 回复  |  直到 6 年前
        1
  •  1
  •   user2357112    6 年前

    蟒蛇是 构造函数的副本。 copy.copy(fun) 刚刚回来 fun ; 不同的是你把它保存到了 fun_cp 变量,与您保存的变量不同 process 对,所以它还在 什么时候 过程

    我会做一些类似于您所做的事情,将原始函数保存到另一个变量,只是不使用“copy”:

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

    如果要将相同的包装应用于多个函数,请定义一个装饰器并执行以下操作 fun = decorate(fun) 它的可重用性更强,但是对于一次性的,它需要更多的工作和额外的缩进。

        2
  •  1
  •   cs95 abhishek58g    6 年前

    这看起来像是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) 
    
        3
  •  0
  •   jmd_dk    6 年前

    import functools
    
    def getprocess(f):
        @functools.wraps(f)
        def process(x):
            x += 1
            return f(x)
        return process
    
    fun = getprocess(fun)
    

    请注意,这100%等同于应用装饰器( getprocess fun . 我无法将此解决方案作为专用的decorator语法 @getprocess 乐趣 ). 但要将其应用于现有函数,只需执行以下操作 fun = getprocess(fun)