Python 装潢师:试着让我的头脑了解它

Python 装潢师:试着让我的头脑了解它,python,decorator,Python,Decorator,我试图了解装饰师,并想尝试以下内容: 假设我有两个decorator并将其应用于函数hello: def wrap(f): def wrapper(): return " ".join(f()) return wrapper def upper(f): def uppercase(*args, **kargs): a,b = f(*args, **kargs) return a.upper(), b.upper()

我试图了解装饰师,并想尝试以下内容:

假设我有两个decorator并将其应用于函数hello:

def wrap(f):
    def wrapper():
        return " ".join(f())
    return wrapper


def upper(f):
    def uppercase(*args, **kargs):
        a,b = f(*args, **kargs)
        return a.upper(), b.upper()
    return uppercase

@wrap
@upper
def hello():
    return "hello","world"

print hello()
然后我必须开始为其他函数添加其他装饰器, 但一般来说,包装装饰师会“包装所有的包装”

现在我该如何编写一个装饰器,用它我可以装饰我的上下装饰器:

@wrap
def lower():
    ...

@wrap
def upper():
    ...
要达到与上述相同的效果,只需执行以下操作:

@upper
def hello():
    ...

@lower
def byebye():
    ...

Python中的装饰程序

 @foo
 def bar(...): ...
只相当于

 def bar(...): ...
 bar = foo(bar)
你想得到的效果

@wrap
@upper
def hello(): ....
i、 e

因此,应在
上限的返回值上调用
换行

def upper_with_wrap(f):
   def uppercase(...): ...
   return wrap(uppercase)
这也相当于在该函数上应用decorator:

def upper_with_wrap(f):
   @wrap
   def uppercase(...): ...
   # ^ equivalent to 'uppercase = wrap(uppercase)'
   return uppercase
这里有一个通用的(稍微复杂的)解决方案,用于用装饰器装饰装饰器(耶!)


这几乎回答了这个问题。你是在装饰一个装饰器,但我不是在寻找一个通用的解决方案,我实际上想要一个更简单的装饰器,因为不管我多么频繁地查看示例,我的大脑都必须绕过参数/任务:)好吧,你当然可以将其设为非通用的。它甚至非常简单:编写
mywrap=decdec(wrap)
,然后使用@mywrap作为装饰器的装饰器。这是一个很好的解决方案,但并不完全是我要问的,尽管也许我应该在问题中说得更清楚。虽然使用这种技术更干净(更容易理解),但我正在研究如何显式地装饰装饰器。不过,你得到了我的支持,希望我能给予更多,特别是在解释你的答案时所花的时间:)正是我想要的!您可能想阅读以下内容:。最后有一个装饰师的例子,但是答案会慢慢地介绍给你。
hello = wrap(upper(hello))
def upper_with_wrap(f):
   def uppercase(...): ...
   return wrap(uppercase)
def upper_with_wrap(f):
   @wrap
   def uppercase(...): ...
   # ^ equivalent to 'uppercase = wrap(uppercase)'
   return uppercase
# A second-order decorator
def decdec(inner_dec):
    def ddmain(outer_dec):
        def decwrapper(f):
            wrapped = inner_dec(outer_dec(f))
            def fwrapper(*args, **kwargs):
               return wrapped(*args, **kwargs)
            return fwrapper
        return decwrapper
    return ddmain

def wrap(f):
    def wrapper():
        return " ".join(f())
    return wrapper


# Decorate upper (a decorator) with wrap (another decorator)
@decdec(wrap)
def upper(f):
    def uppercase(*args, **kargs):
        a,b = f(*args, **kargs)
        return a.upper(), b.upper()
    return uppercase

@upper
def hello():
    return "hello","world"

print hello()