令人困惑的结果(对我来说)在Python 3中使用Decorator

时间:2017-03-19 17:30:13

标签: python for-loop closures decorator

我甚至不知道如何正确地说出这个问题(所以我不知道之前是否讨论过这个话题或者如何查询它)。
下面的代码给我留下了令人难以置信的东西。 这是对装饰者的练习。特别是这个是为了演示Decorator如何在字符串的开头和结尾添加HTML标签。 如果我要调用一个使用装饰器返回字符串的函数: @AddTags( 'P', 'I', 'b')的 返回值是:  “ p i b *欢迎Joe加入我的博客! * b i p

for loop 如何返回包含所有值的单个一行。 如果我们不使用“反转”,那么结果如何倒退呢? 我开始理解装饰器的概念,但这个例子就像纯粹的魔术......这是如何工作的?

    def AddTags(*tags):
    def decorator(oldFunc):
        def inside(*args, **kwargs):
            code = oldFunc(*args, **kwargs)
            for tag in reversed(tags):
                code = "<{0}>{1}</{0}>".format(tag,code)
            return code
        return inside
    return decorator
@AddTags("p","i","b")
def MyWebWelcome(name):
    return "Welcome "+name+" To my blog!"

1 个答案:

答案 0 :(得分:1)

没有魔力,只是code = "<{0}>{1}</{0}>".format(tag,code)不断更新code的扩展版本。通过反转循环的标记,确保首先添加最右边的标记,然后由下一个标记包装,依此类推。您可以通过几个打印语句来查看进度:

def AddTags(*tags):
    def decorator(oldFunc):
        def inside(*args, **kwargs):
            code = oldFunc(*args, **kwargs)
            for tag in reversed(tags):
                print('code:', code)
                code = "<{0}>{1}</{0}>".format(tag,code)
            return code
        return inside
    return decorator

@AddTags("p","i","b")
def MyWebWelcome(name):
    return "Welcome "+name+" To my blog!"

print('result:', MyWebWelcome('foo'))

打印

code: Welcome foo To my blog!
code: <b>Welcome foo To my blog!</b>
code: <i><b>Welcome foo To my blog!</b></i>
result: <p><i><b>Welcome foo To my blog!</b></i></p>

它对装饰者来说也没什么神奇之处。我可以只运行循环:

>>> code = "foo"
>>> for tag in ("p", "i", "b"):
...     print(code)
...     code = "<{0}>{1}</{0}>".format(tag,code)
... 
foo
<p>foo</p>
<i><p>foo</p></i>
>>> code
'<b><i><p>foo</p></i></b>'