在一个Python脚本中加载2种不同版本的库

Posted woshiaotian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在一个Python脚本中加载2种不同版本的库相关的知识,希望对你有一定的参考价值。

起因: 从ES集群A往ES集群B导数,然后比对2个ES的数据差异,逐个ID比对。由于ES集群A的版本是1.4.x,ES集群B的版本是5.3.x,所以无法使用同一个ES client包

1. 加载不同版本的client包

对比的过程是,取相同发布时间区间的文章ID,然后比对id的差异
伪码如下:

es_A_ids = get_es_A_ids()
es_B_ids = get_es_B_ids()
diff_ids = es_A_ids - es_B_ids

可以想到的是在访问完集群A后重新加载elasticsearch 库

## load elasticsearch==1.4.0
es_A_ids = get_es_A_ids()
## load elasticsearch==5.3.0
es_B_ids = get_es_B_ids()
diff_ids = es_A_ids - es_B_ids

但是很有趣的是,elasticsearch在load完上一个版本以后,它的版本没有发生变化

2. 清理已经load 的module

经过查资料,我明确了这个问题,python的module,只会被load,有且一次,所以要保证不同版本的module被再次load,只能先clear 原先load的module
ES的module都以elasticsearch开头,因此把它们都清理掉

for key in sys.modules.keys():
    if key.startswith('elasticsearch'):
        del sys.modules[key]

完整代码

import importlib
import sys
# use elasticsearch 5.x
es_lib_path = "/Users/woshiaotian/es_5x/lib/python2.7/site-packages"
# 注意要把es_lib_path放在sys.path 的首位,确保load module的时候,该目录下的ES库,能够被优先加载
sys.path.insert(0, es_lib_path)  
#print sys.path
elasticsearch = importlib.import_module("elasticsearch")
print elasticsearch
sys.path.pop(0)

for key in sys.modules.keys():
    if key.startswith('elasticsearch'):
        print  key
        del sys.modules[key]

# use elasticsearch 1.x
es_lib_path = "/Users/woshiaotian/es_1x/lib/python2.7/site-packages"
sys.path.insert(0, es_lib_path)
elasticsearch = importlib.import_module("elasticsearch")
print elasticsearch
sys.path.pop(0)
#print sys.path

for key in sys.modules.keys():
    if key.startswith('elasticsearch'):
        print  key
        del sys.modules[key]

sys.modules
This is a dictionary that maps module names to modules which have already been loaded. This can be manipulated to force reloading of modules and other tricks. However, replacing the dictionary will not necessarily work as expected and deleting essential items from the dictionary may cause Python to fail.

参考资料

  1. https://docs.python.org/3/library/sys.html

以上是关于在一个Python脚本中加载2种不同版本的库的主要内容,如果未能解决你的问题,请参考以下文章

当存在 2 个版本的库时按需在 tomcat 中加载类?

如何在脚本中加载 tflite 模型?

在同一个项目中加载多个 jquery 版本但不同的页面

如果在同一个 AppDomain 中加载了多个版本,WPF 无法选择正确的 DLL

如何在python海龟游戏中加载不同的关卡

无法在仅 TensorFlow CPU 版本中加载模型