Python装饰器我遇到奇怪的错误

时间:2015-06-19 05:11:52

标签: python python-decorators

我的代码非常简单。它是一个测试,但我收到一个很大的错误:nonetype不可调用:

def deco(when):
    def wrapper(fun):
        print 'before call myfun'
        fun()
        print 'after call myfun' 
    return wrapper 
@deco('a')
def fun():
    print 'in fun1'
fun()

但稍微修改后,错误就会被删除:

def deco(when):
    def wrapper(fun):
        def dec():
            print 'before call myfun'
            fun()
            print 'after call myfun'
        return dec
    return wrapper

@deco('a')
def fun():
    print 'in fun'
fun()
你能说出原因吗?我完全糊涂了。

另外,在第二个代码块中,methon wrapper()如何访问变量'fun',变量'fun'不在上下文中(上层的arg是'当'而不是“有趣”,我也很困惑。

谢谢你的帮助

2 个答案:

答案 0 :(得分:3)

装饰器是一个接受函数并返回新函数的函数。它通常看起来像

def deco(fun):
    def wrapped(*args, **kwargs):
        # something... 
        return fun(*args, **kwargs)
    return wrapped

@之后的表达式必须返回装饰器。如果该表达式是一个函数调用,那么它调用的函数必须返回一个装饰器。因此,它必须看起来像

def deco_with_args(arg):
    def deco(fun): # The decorator function that will be returned
        def wrapped(*args, **kwargs): # The wrapper function that will finally be assigned to the decorated name
            # something... 
            return fun(*args, **kwargs)
        return wrapped
     return deco

答案 1 :(得分:0)

当装饰器提供参数时,它被视为'装饰器生成器',并且必须返回适当的装饰器。

另见python decorators with parameters