Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
285 views
in Technique[技术] by (71.8m points)

python - decorating decorators: try to get my head around understanding it

I'm trying to understand decorating decorators, and wanted to try out the following:

Let's say I have two decorators and apply them to the function 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()

Then I have to start adding other decorators for other functions, but in general the wrap decorator will "wrap all of them"

def lower(f):
    def lowercase(*args, **kargs):
        a,b = f(*args, **kargs)
        return a.lower(), b.lower()
    return lowercase

@wrap
@lower
def byebye():
    return "bye", "bye"

Now how do I write a decorator, with witch I can decorate my lower and upper decorators:

@wrap
def lower():
    ...

@wrap
def upper():
    ...

To achieve the same result as above by only doing:

@upper
def hello():
    ...

@lower
def byebye():
    ...
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
def upper(f):
    @wrap
    def uppercase(*args, **kargs):
        a,b = f(*args, **kargs)
        return a.upper(), b.upper()
    return uppercase

A decorator in Python

 @foo
 def bar(...): ...

is just equivalent to

 def bar(...): ...
 bar = foo(bar)

You want to get the effect of

@wrap
@upper
def hello(): ....

i.e.

hello = wrap(upper(hello))

so the wrap should be called on the return value of upper:

def upper_with_wrap(f):
   def uppercase(...): ...
   return wrap(uppercase)

which is also equivalent to applying the decorator on that function:

def upper_with_wrap(f):
   @wrap
   def uppercase(...): ...
   # ^ equivalent to 'uppercase = wrap(uppercase)'
   return uppercase

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...