-
А может быть я что-то делаю не так? Как вот вы решаете задачу поддержки различных версий библиотек/протоколов, при условии, что их нельзя обернуть во враппер, который уравняет их поведение?
-
@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, при том что в каждой версии своя специфика и при этом нужно иметь поддержку всех версий в одном модуле + тесты для каждой версии. -
@kb, никак(: декоратор их собирает в себя, складывает по неймспейсу и потом вызывает нужную в зависимости от current и minimal версий. Проще кодом: python.pastebin.com
-
@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 искать, но было лень(: да и случай крайне специфичный