在装饰器中定义函数

时间:2009-07-17 07:50:11

标签: python aop decorator argument-passing

为什么这不起作用?我怎样才能使它工作?也就是说,如何在我的装饰函数中使用gu?

def decorate(f):
    def new_f():
        def gu():
            pass
        f()
    return new_f

@decorate
def fu():
    gu()

fu()

我是否需要以某种方式将gu添加到已定义函数的字典中?或者我可以在调用之前将gu添加到f的本地名称空间吗?

5 个答案:

答案 0 :(得分:2)

如果您需要将gu传递给fu,则需要通过参数明确执行此操作:

def decorate(f):
    def new_f():
        def gu():
            pass
        f(gu)
    return new_f

@decorate
def fu(gu):
    gu()

fu()

答案 1 :(得分:1)

gu new_f 函数的本地函数,它是 decorate 函数的本地函数。

答案 2 :(得分:1)

gu()仅在new_f()中定义。除非您将其返回或将其锚定到new_f()或其他内容,否则无法从外部引用new_f()

我不知道你在做什么,但这个计划看起来非常复杂。也许你可以找到一个不太复杂的解决方案。

答案 3 :(得分:0)

原则上,你可以使用与旧代码相同的代码创建一个新函数,但用全局范围代替修改后的代码:

import new

def with_bar(func):
    def bar(x):
        return x + 1
    f_globals = func.func_globals.copy()
    f_globals['bar'] = bar
    return new.function(func.func_code, f_globals,
                        func.func_name, func.func_defaults, func.func_closure)

@with_bar
def foo(x):
    return bar(x)

print foo(5) # prints 6

在实践中,你真的应该找到一个更好的方法来做到这一点。将函数作为参数传递是一种选择。可能还有其他方法,但如果没有高级别的问题描述,很难说出什么是合适的。

答案 4 :(得分:0)

为什么不让你的装饰者成为一个类而不是一个函数?这显然是可能的,正如我在查看property内置的帮助时发现的那样。 (以前,我曾经认为你只能将装饰器应用于类,而不是装饰器本身可以是类。)

(当然,gu必须是类或内部类的方法。)