Pergunta

i was looking at a file wicd-curses.py from the wicd application available with urwid. there is a function named as wrap_exceptions and then at several other places in the file i find some code like this @wrap_exceptions which occurs just before several other functions. What does it mean ?

Foi útil?

Solução

These are called decorators.

Decorators are methods that accept another method as input. The decorator will then do something to the given function in order to change the output.

In mathematical terms, decorators can be looked at somewhat like g(f(x)) where g is the decorator and f is the original function to be decorated. Decorators can do anything to the given function, but usually they wrap them in some sort of validation or error management.

This blog has an excellent explanation of decorators; an example from this is a wrapper method that checks parameters in a simple coordinate system:

class Coordinate(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return "Coord: " + str(self.__dict__)

def inputChecker(func):
    def checker(a, b): # 1
        if a.x < 0 or a.y < 0:
            a = Coordinate(a.x if a.x > 0 else 0, a.y if a.y > 0 else 0)
        if b.x < 0 or b.y < 0:
            b = Coordinate(b.x if b.x > 0 else 0, b.y if b.y > 0 else 0)
        ret = func(a, b)
        if ret.x < 0 or ret.y < 0:
            ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y > 0 else 0)
        return ret
    return checker

# This will create a method that has automatic input checking.
@inputChecker
def addChecked(a, b):
    return Coordinate(a.x + b.x, a.y + b.y)

# This will create a method that has no input checking
def addUnchecked(a, b):
    return Coordinate(a.x + b.x, a.y + b.y)

one = Coordinate(-100, 200) # Notice, negative number
two = Coordinate(300, 200)

addChecked(one, two)
addUnchecked(one, two)

When the coordinates are added together with addChecked, it ignores the negative number and assumes it is zero; the result of it is: Coord: {'y': 400, 'x': 300}. However, if we do addUnchecked, we get Coord: {'y': 400, 'x': 200}. This means that in addChecked, the negative value was ignored by the decorator's input checking. The variables passed in are not changed - only the local a and b inside checker(a, b) are corrected temporarily.

Edit: I added a small explanation and expanded on one of the examples in the blog in response to dkar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top