Как поддерживать несколько версий зависимости Python?

#python

Вопрос:

Я пишу утилиту python, которая должна поддерживать несколько LTS-версий библиотеки python. Допустим, версии LTS являются «1.0» и «2.0».

В 2.0 библиотеки есть методы, которые имеют другую сигнатуру по сравнению с 1.0, например:

 # Version 1.0
def display_name(self, name):
    ...

# Version 2.0
def display_name(self, name, param_2):
    ...

 

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

Теперь мой вопрос в том, как поддерживать несколько версий зависимости Python? Изменений не так много, всего таких серьезных различий около 10 с лишним.

До сих пор я пробовал / придумывал следующие идеи (другие идеи более чем приветствуются):

  1. Создайте 2 разные версии моей библиотеки, которые поддерживают 2 разные версии. Сохраняйте имя версии, аналогичное основной библиотеке, чтобы люди могли иметь к ней отношение, и проводите проверку при загрузке библиотеки, чтобы убедиться, что установлен поддерживаемый основной инструмент.
  2. Есть 1 версия моей библиотеки и добавьте своего рода проверку условий if перед каждым вызовом такого метода, который ожидает другой параметр, и в зависимости от версии вызывайте разные методы. Как много библиотек поддерживают python 2.* и 3.*
  3. Расширяя вариант 2, можно ли написать какой-либо шаблон декоратора, который делегирует, какая версия метода будет загружена/вызвана?

Пример:

 # Is something like this possible?
@lib_ves_1
def my_lib_method(self, args):
    ...
    main_lib.display_name(name)

@lib_ves_2
def my_lib_method(self, args):
    ...
    main_lib.display_name(name, param_2)

 

PS: Любой другой подход/идея более чем приветствуется.

Спасибо

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

1. Просто потому, что вопрос (по вашему мнению) основан на мнении, не означает, что это плохой вопрос. Этот вопрос соответствует руководящим принципам, установленным для постановки трудного вопроса: meta.stackexchange.com/questions/278843/.

2. Я спрашиваю, как можно сделать «x», и я поделился тем, что все, что я пробовал до сих пор. «Варианты» != «Мнение».

3. Очевидно, что если он закрыт и не открыт вновь, это не только мое мнение… И речь идет не о том, чтобы назвать вопрос плохим или хорошим.

Ответ №1:

Вместо вашего варианта (2) — проверка версии библиотеки перед каждым вызовом, вы можете либо определить правильную версию своих функций во время импорта:

 import thelib

if thelib.__version__ >= 2.0:
    def my_function():
        return thelib.action1(43, 21)
else:
    def my_function():
        return thelib.action1(43)
 

Возможно, еще лучше определить тонкую оболочку над библиотекой, которая объединяет вызовы, чтобы у вас были все «различия» в одном месте, и ваш фактический код не должен разветвляться для этой цели. Это в значительной степени то, что делает инструмент six — уровень совместимости между python2 и 3.

 import thelib

if thelib.__version__ >= 2.0:
    def action1_wrapper():
        return thelib.action1(43, 21)
else:
    def action1_wrapper():
        return thelib.action1(43)

def my_library_function():
    # ...
    action1_wrapper()
    # ...
 

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

1. Спасибо, определение этого во время импорта имеет смысл. это поможет сократить количество проверок if. Я проголосовал за ответы. Извините, если из-за «мнения», что мой вопрос основан на «мнении», поэтому они все отвергают. Спасибо вам за вашу помощь.

2. Я не принимаю ответ, потому что я надеюсь на какое-то другое решение, которое может сделать это с некоторыми декораторами, возможно, это сделало бы его действительно простым. Но спасибо за помощь 🙂