How to use two Python text decorators?

Asked

Viewed 123 times

3

How can I make to use two decorators in python, as in the example below:

@makebold
@makeitalic
def say():
   return "Hello"

returning:

<b><i>Hello</i></b>

I’m not trying to make HTML like this in a real application, I’m just trying to understand how decorators and groups of decorators work in Python.

2 answers

2


Just define the functions:

def makebold(fn):
    def pacote():
        return "<b>" + fn() + "</b>"
    return pacote

def makeitalic(fn):
    def pacote():
        return "<i>" + fn() + "</i>"
    return pacote

@makebold
@makeitalic
def hello():
    return "Olá Mundo"

print hello() ## retorno <b><i>Olá Mundo</i></b>

See this example on codepad.

Note that it is essential to use packaging ( wrapping) In these delimiters, the problem is that people in general believe that delimiters do compound functions. What doesn’t happen without this kind of packaging.

1

Definition:

Decorators are functions returning another function using the syntax of @wrapper or packaging.

As described in official documentation decorators are nothing more than syntactic sugar.

For example the two definitions below are equivalent:

def f(...):
    ...
f = metodoestatico(f)

@metodoestatico
def f(...):
    ...

Utilizing

In addition to the very example given in the question and answer. It is possible to use decorators for other purposes and even to make a debug more efficient:

 def debugger(func):
    def f_interna(*args, **kwargs): #1
        print "Os argumentos foram: %s, %s" % (args, kwargs)
        return func(*args, **kwargs) #2
    return f_interna
@debugger
def foo1(x, y=1):
    return x * y
@debugger
def foo2():
    return 2

Exit

>>> foo1(5, 4)
Os argumentos foram: (5, 4), {}
20
>>> foo1(1)
Os argumentos foram: (1,), {}
1
>>> foo2()
Os argumentos foram: (), {}
2

Stack (or grouping of decorators)

To use more than one decorator it is necessary to do an internal packaging in the decorating functions as shown in another answer:

def makebold(fn):
    def pacote():
        return "<b>" + fn() + "</b>"
    return pacote

def makeitalic(fn):
    def pacote():
        return "<i>" + fn() + "</i>"
    return pacote

Browser other questions tagged

You are not signed in. Login or sign up in order to post.