• dev Python ? Интересно. Перерыв пол интернета так и не нашел декоратора, который выполняет одну простую вещь: версионирует функции/методы/классы и вызывает нужную в зависимости от текущей версии питона/библиотеки/сервиса/неважно-чего. По моему, идея достаточно вкусная и красивая — чем городить деревья if-else или держать разные модули под разные версии, тут все находится в одном и том же месте и визуально различимо. С другой стороны бардак одноименных функций и навигатор по коду сходит с ума, но это вроде не такая большая плата за удобство. И задача в общем-то не оказалась такой сложной.
    А может быть я что-то делаю не так? Как вот вы решаете задачу поддержки различных версий библиотек/протоколов, при условии, что их нельзя обернуть во враппер, который уравняет их поведение?
  • не совсем ясно. Тоесть в случае одной библиотеки тебе надо чтоб отработал один код, а в случае другой — другой код. И как ты собираешься решить эту проблему декораторами? Просто отдели логическую функцию, которая выполняет задачу, а там уж внутри делает if else. Или я чего не понял.
  • @kb, да, так нужно разделить поведение для различных версий модулей. В моем случае функционал зависит от версии couchdb сервера.
    Классически разделить через if-else это получится нагромождение кода в одной функции. Pythonic-way через вложенные функции и словарь с ключами версий — уже лучше, но мне эстетически не нравится именование локальных функций + когда много функций, которые нужно версионировать подобным методом, несколько приедается получаемая рутина.

    в итоге вышло нечто такое:
    @version.minimal(0, 9, 0)
    def handler(*args):
    ...
    return max(args)

    @version.minimal(0, 10, 0)
    def handler(*args):
    ...
    return min(args)

    version.current = (0, 9, 5)
    handler(1, 2, 3)

    Тут ведь еще какая загвоздка в моем случае — вью сервер кауча очень сильно изменил свой протокол, если смотреть линейку от 0.9 до 1.0, при том что в каждой версии своя специфика и при этом нужно иметь поддержку всех версий в одном модуле + тесты для каждой версии.
  • @Kxepal, ээ, что-то я не очень понял как получится две функции с именем одинаковым вызвать
  • @kb, никак(: декоратор их собирает в себя, складывает по неймспейсу и потом вызывает нужную в зависимости от current и minimal версий. Проще кодом: python.pastebin.com
  • @Kxepal, ух... Думаю — многовато магии, всё же)) но идея прикольная, однозначно.
  • @kb, перепостил без слотов и с импортом, чтобы сразу работал:
    python.pastebin.com
    имхо магия только в получении неймспейса — был крайне опечален, что никак нельзя узнать владельца неймспейса и этот декоратор сломается если будет код

    @Version.minimal(1,2,3)
    def test():
    pass
    abc = test
    del test

    @Version.minimal(1,2,4)
    def test():
    pass

    поскольку первый test был переименован в abc, то и попадет он под версионирование фукнций abc, а не test'ов, поскольку в local scope его больше нет. Можно, конечно, по id искать, но было лень(: да и случай крайне специфичный