简体   繁体   English

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

[英]decorators doesn't work in globals

I set attribute for func by a decorator function, but can not get it in globals() 我通过装饰器函数为func设置了属性,但无法在globals()中获得它

here is the code 这是代码

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)

anybody know why ? 有人知道为什么吗?

The problem lies with your use of globals() ; 问题在于您对globals() it returns a dictionary, and calling list() on a dictionary gives you the keys , not the objects. 它返回一个字典,并在字典上调用list()给您 ,而不是对象。 You are testing against strings here. 您正在此处针对字符串进行测试。

Use: 采用:

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

The list() is still needed as the code adds 2 extra globals ( name and obj ), so the globals() dictionary changes size in the first iteration, something that'll throw an exception otherwise. 由于代码中添加了两个额外的全局变量( nameobj ),因此仍需要list() ,因此globals()字典在第一次迭代中会更改大小,否则会引发异常。

Your decorator is working fine otherwise. 否则,您的装饰器工作正常。

Indeed it is in globals. 确实是全球性的。

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

The point is when iterate over globals (even in na list), it will be a string representation of item of globals. 关键是当遍历全局变量(即使在na列表中)时,它将是全局变量项的字符串表示形式。

So should try this way 所以应该尝试这种方式

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

Anyway every object will appear as a string. 无论如何,每个对象都将显示为字符串。 This only will asserts that this object is in globals. 这只会断言该对象位于全局变量中。

I recommend you to read about scoping and namesapecing. 我建议您阅读有关作用域和名称分隔的信息。 This is a good article about it. 是一篇很好的文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM