具有不同库函数签名的两个不同环境中的相同代码 运行

same code running in two different environments with different library function signatures

我需要在两个不同的 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)

这是 pythonic 的方式吗?

您可以试试看版本:

>>> 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

Python 函数是对象,并且是它们模块的属性,所以你可以在启动时(即在你的主脚本中)只对模块进行一次 monkeypatch:

# 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.

检索已加载的模块