Что означает конструкция @ code в python?

Я искал файл wicd-curses.py из приложения wicd, доступного с помощью urwid. есть функция с именем wrap_exceptions, а затем в нескольких других местах файла я нахожу некоторый код, подобный этому @wrap_exceptions, который происходит непосредственно перед несколькими другими функциями. Что это значит?

1 ответ

Решение

Это так называемые декораторы.

Декораторы - это методы, которые принимают другой метод в качестве входных данных. Затем декоратор сделает что-то с данной функцией, чтобы изменить вывод.

С математической точки зрения декораторы могут выглядеть как g(f(x)) где g это декоратор и f это оригинальная функция для оформления. Декораторы могут делать что угодно с данной функцией, но обычно они заключают их в своего рода валидацию или управление ошибками.

Этот блог имеет отличное объяснение декораторов; Примером этого является метод-оболочка, который проверяет параметры в простой системе координат:

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)

Когда координаты добавляются вместе с addChecked, он игнорирует отрицательное число и предполагает, что оно равно нулю; результат этого: Coord: {'y': 400, 'x': 300}, Тем не менее, если мы делаем addUnchecked, мы получаем Coord: {'y': 400, 'x': 200}, Это означает, что в addCheckedотрицательное значение было проигнорировано проверкой входных данных декоратора. Переданные переменные не изменены - только локальные a а также b внутри checker(a, b) исправлены временно.

Изменить: я добавил небольшое объяснение и расширил один из примеров в блоге в ответ на dkar.

Другие вопросы по тегам