один и тот же код работает в двух разных средах с разными сигнатурами библиотечных функций - PullRequest
0 голосов
/ 11 декабря 2018

Мне нужно запустить некоторый код в двух разных средах Python.Есть одна библиотека, в которой я использую две разные версии.

Env1.
mylib.myfun(*args) # as expected
mylib.myfun(*args,extra_arg=val) # raise error

Env2.
mylib.myfun(*args) # raise warning
mylib.myfun(*args,extra_arg=val) # as expected

В идеале я хотел бы запустить один и тот же идентичный код и получить одинаковые результаты в двух средах.Я думал об этом с помощью приспособления

def fix_myfun():
    if mylib.version<needed:
       mylib.myfun(*args)
    else:
       mylib.myfun(*args)

Это ли питонский способ сделать это?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Функции Python являются объектами и являются атрибутами их модулей, так что вы можете просто установить модуль один раз при запуске (т.е. в вашем основном скрипте):

# this has to be executed BEFORE any use of `mylib.myfun`
import mylib

def patch_myfun():
    realfun = mylib.myfun

    if mylib.version < needed:
        # Env 1
        def patched(*args, extra_arg=None):
            return realfun(*args)
    else:
        # Env 2
        def patched(*args, extra_arg=None):
            return realfun(*args, extra_arg=extra_arg)

    mylib.myfun = patched


patch_my_fun()

Примечание: этот код должен выполняться толькоконечно, один раз за процесс (иначе myfun будет исправлено более одного раза).Лучший способ убедиться в этом - поместить его в верхнюю часть скрипта или в модуль, который импортируется перед любым использованием mylib.myfun - для модуля код верхнего уровня выполняется только один раз (для каждого процесса) в первый раз.после импорта модуля следующий импорт извлечет только загруженный модуль из sys.modules.

0 голосов
/ 11 декабря 2018

Вы можете попробовать его для проверки версии:

>>> import re
>>> print re.__version__
2.2.1
>>> re.__version__ == "2.2.1"
True

И проверить:
(Здесь я показываю, как проверить версию 2.2.2 и новее.)

>>> bool(re.match(r"2.2.(?:[2-9]|\d\d\d*)", re.__version__))
False
>>> bool(re.match(r"2.2.(?:[2-9]|\d\d\d*)", "2.2.2"))
True
...