Декоративные изыски

Пока пост про спринт с фотками и видео по техническим причинам задерживает, я решил поразмышлять вслух о декораторах.

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

Причем количество декораторов применимых к функции не ограничено, а следовательно можно очень сильно изменить первоначальное поведение.

Но тут встает эстетический вопрос, насколько удобно и практично писать код, который выглядит примерно так:

@a
@bb("dd","ff")
@ccc
def foobar(arg1,arg2):
   #...

Т.е. получается "декоратор на декораторе". Я не вижу в этом ничего плохого и считаю, что это никак не мешает восприятию. А наоборот, благодаря некой декларативности, помогает лучше структурировать код. Даже если учесть альтернативный, "старый" вариант их использования.

Конечно, иногда декораторы избыточны. Если мы сами авторы функции, то мы можем и не использовать декораторы, а просто явно вызывать некие сторонние функции, которые делают работу декораторов. Но для этого надо чуть-чуть больше знать о том, что они делают и как. И к тому же мы теряем, так любимою мною, декларативность и "скатываемся" до условно императивных конструкций. Код выше мог бы выглядеть так:

def foobar(arg1,arg2):
   arg1 = a(arg1)
   arg2 = bb("dd","ff", arg2)
   if not arg2:
        return
   #...
   return ccc(some_result)

Вам так больше нравится? Мне определенно нет. Переписав всё без декораторов, мы мыло того что увеличили объем кода, так ещё и уменьшили его декомпозицию, перенеся часть "лишней" логики в нашу функцию.

Так вот, мой вывод - декораторы нужно использовать часто, если с их использованием, код получается стройнее и выразительнее. Даже не смотря на возможные потери из-за "декораторной обвязки", которые можно и сократить (время написания) воспользовавшись модулем decorators, если конечно вам не нужно совместимость со старым питоном:)

Вот я за собой заметил, что стал чаще ими пользоваться. И мне пока нравится.

А какое ваше мнение о декораторах и их активном применении?

Комментарии 8

  1. Fox написал:

    Скудный пример какой. Можно поправить. Как будет выглядеть функция foobar после применения декараторов. Я бы начал до и после применения декаратора. А не после и до. Я сталкивался с декаратором только в авторизации django. Хотелось бы получше разобраться в их сути.

    Оставлен 18 Июль 2008 в 01:19
  2. Иван Сагалаев написал:

    Так вот, мой вывод - декораторы нужно использовать часто, если с их использованием, код получается стройнее и выразительнее.

    Учитывая часть после "если", вместо слова "декораторы" можно поставить любую фичу языка :-)

    А какое ваше мнение о декораторах и их активном применении?

    К сожалению, их довольно легко абьюзить. Когда основная семантика функции переткает в декораторы, когда сама функция пишется в расчете на определенные декораторы и без них не работает, возвращая просто неверные результаты, это для меня плохие признаки. Хотя тут никаких четких правил, конечно, нет. Принцип "если код получается стройнее и выразительнее" бьет любые догмы. Хуже, если не получается :-)

    Оставлен 18 Июль 2008 в 02:44
  3. bw написал:

    Очень редко приходится создавать свои декораторы. Примерно 1 декоратор на 3-5 тыс. строк кода :-). Очень часто использую staticmethod и classmethod. Посмею предположить, что потребность в декораторах тем выше, чем меньше вы используете ООП.

    ..bw

    Оставлен 18 Июль 2008 в 13:53
  4. Александр Кошелев написал:

    Скудный пример какой. Можно поправить. Как будет выглядеть функция foobar после применения декараторов. Я бы начал до и после применения декаратора. А не после и до.

    А я начал так;)

    Я сталкивался с декаратором только в авторизации django. Хотелось бы получше разобраться в их сути.

    Пожалуйста PEP-318

    Оставлен 18 Июль 2008 в 14:38
  5. meowth написал:

    Если копнуть глубже, получается, что питоновский декоратор суть weaver в терминологии фспектно-ориентированного программирования. Так что ничего странного в том, что он делает сам код читабельнее, гибче, явно разнося ответственность по классам, нет - это ожидаемое поведение.

    С другой стороны, кк указал Иван Сагалаев, когда много функционала переносится в динамику - т.е., он реализуется не статичными классами, взаимоотношение которых достаточно легко можно увидеть в коде, а композицией объектов в рантайме, код зачастую сложнее понимать, изменять и т.д. - если таких объектов много, понимабельность падает экспоненциально.

    Оставлен 18 Июль 2008 в 16:13
  6. Александр Кошелев написал:

    Когда основная семантика функции переткает в декораторы, когда сама функция пишется в расчете на определенные декораторы и без них не работает, возвращая просто неверные результаты, это для меня плохие признаки. Хотя тут никаких четких правил, конечно, нет. Принцип "если код получается стройнее и выразительнее" бьет любые догмы. Хуже, если не получается :-)

    Да. Согласен. Иногда декораторы превращаются в конструктор из которого по кусочкам складывается нужный функционал. Если правила четко "прописаны", то я не считаю это чем-то плохим. Хотя конечно поддержка и сопровождение усложняются.

    Оставлен 19 Июль 2008 в 00:18
  7. Александр Кошелев написал:

    Примерно 1 декоратор на 3-5 тыс. строк кода :-).

    Не плохо, но у меня чаще;)

    Посмею предположить, что потребность в декораторах тем выше, чем меньше вы используете ООП.

    Может быть. Но мне кажется, что это не так.

    Оставлен 19 Июль 2008 в 00:35
  8. Александр Кошелев написал:

    Если копнуть глубже, получается, что питоновский декоратор суть weaver в терминологии фспектно-ориентированного программирования.

    Возможно. Так глубоко не копал:)

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

    В питоне, как мне кажется, слово статически вообще чужеродно...

    Оставлен 19 Июль 2008 в 00:37