Python 装饰器名称错误

Python 装饰器名称错误,python,python-decorators,Python,Python Decorators,考虑一下这个简单的decorator演示: class DecoratorDemo(): def _decorator(f): def w( self ) : print( "now decorated") f( self ) return w @_decorator def bar( self ) : print ("the mundane") d = Decorato

考虑一下这个简单的decorator演示:

class DecoratorDemo():

    def _decorator(f):
        def w( self ) :
            print( "now decorated")
            f( self )
        return w

    @_decorator
    def bar( self ) :
        print ("the mundane")

d = DecoratorDemo()
d.bar()
运行此命令将获得预期的输出:

now decorated
the mundane
d.bar
d.\u decorator
的类型确认为
,如果我在上述代码的末尾添加以下两行

print(type(d.bar))
print(type(d._decorator))
现在,如果我在定义
\u decorator
方法之前修改上面的代码来定义
bar
方法,我会得到错误

     @_decorator
NameError: name '_decorator' is not defined

为什么方法的顺序与上述情况相关

因为修饰的方法实际上并不像看上去那样是一个“方法声明”。decorator语法suger隐藏的是:

def bar( self ) :
    print ("the mundane")
bar = _decorator(bar)

如果将这些行放在
\u decorator
的定义之前,那么名称错误并不令人意外。正如@Daniel Roseman所说,类主体只是代码,是自上而下执行的。

为什么不呢?类主体是可执行代码,与所有代码一样,它是自上而下处理的。就像在模块中装饰函数之前必须定义装饰器一样,在类中装饰方法之前必须定义装饰器。记住,
@
只是
thing=decorator(thing)
的语法糖。这个问题并不像看上去那么愚蠢。许多语言只允许您在某些情况下引用稍后定义的内容。事实上,即使在Python中,您也可以在函数实现中“调用”尚未定义的方法(因为调用是在运行时解析的)。理解何时何地在引用之前必须定义,这既不是琐碎的,也不是毫无意义的。