评估decorator参数会导致NameError

时间:2015-02-07 04:45:57

标签: python decorator

我有一个带有一个参数的装饰器:

def supportSlice(ret_type=None):
    ...

我希望将它应用于类的成员函数,并将类本身作为参数:

class BitArray:
    @supportSlice(ret_type=BitArray)
    def __getitem__(self, idx):
        ...

但是在评估@supportSlice(ret_type=BitArray)时,我得到了一个N​​ameError,说“名称'BitArray'未定义”。看起来装饰器没有在我期望的环境中进行评估。

我的问题是,何时评估成员函数的装饰器?还有什么可以实现我上面描述的目标吗?

1 个答案:

答案 0 :(得分:3)

在装饰器运行时(在class BitArray体内),名称BitArray尚未定义!一个类的名称在之后定义,其主体完成后,其元类(通常为type)构建类对象。

最简单的解决方法是将ret_type的确定延迟到以后......:

def supportSlice(ret_type=None):
    def wrapper(func):
        def wrapfunc(self, *a, **k):
          if ret_type is None:
              rt = type(self)
          else:
              rt = ret_type
          # rest here, using rt
        return wrapfunc
    return wrapper

(当然,如果您不需要强制ret_typetype(self)不同,那么您可以使用无arg装饰器,从而失去一级函数嵌套:)。< / p>