装饰器在全局变量中不起作用

时间:2014-08-05 11:18:12

标签: python decorator python-decorators

我通过装饰器函数为func设置属性,但是无法在globals()

中获取它

这是代码

def tag(name):
    def do_it(func):
        func.tag = name
        return func
    return do_it


@tag('p')
def article():
    return 'article here'


@tag('h1')
def title():
    return 'title here'

# we got attribute here
assert hasattr(article, 'tag', None)

# I got nothing here
for obj in list(globals()):
    if hasattr(obj, 'tag'):
        print(obj)

有谁知道为什么?

2 个答案:

答案 0 :(得分:4)

问题在于您使用globals();它返回一个字典,并在字典上调用list()为您提供,而不是对象。你在这里测试字符串。

使用:

for name, obj in list(globals().items()):
    if hasattr(obj, 'tag'):
        print name

由于代码添加了2个额外的全局变量(list()name),因此仍需要obj,因此globals()字典会在第一次迭代中更改大小,否则会抛出异常。

你的装饰师工作正常。

答案 1 :(得分:0)

确实是全球化的。

def tag(name):
    def do_it(func):
        func.tag = name
        return func
    return do_it

@tag('p')
def article():
    return 'article here'

'tag' in globals()
True

关键是迭代全局变量(甚至在na列表中),它将是全局变量项的字符串表示。

所以应该尝试这种方式

for obj in globals():
    if obj == 'tag':
        print(obj)

无论如何,每个对象都会显示为一个字符串。这只会断言这个对象是全局的。

我建议你阅读有关范围和名称的内容。 This是关于它的好文章。