2

简短
如果已经导入了同名的不同模块,我如何导入模块?我不再需要旧模块,但我无法以不同的名称导入新模块。 importlib.reload()没有达到预期的效果,显然你真的不应该搞砸sys.modules

上下文
我正在通过编写脚本 (A) 来自动化测试工作流程。提供了测试脚本,不能更改。
测试的目标是脚本(B)中的一个类,其子文件夹中有不同的版本。不幸的是,脚本 B 和类总是具有相同的名称,对此我无能为力。

main_folder  
├──script_a.py  
├──test_script.py 
│ 
├──version_1
│    ├──script_b.py    
│
├──version_2  
│    ├──script_b.py 
│ 
├──version_3  
│    ├──script_b.py 

测试脚本导入对象并在其上运行测试。

# test_script
from script_b import my_class 

# creat instance of my_class
# and test it

script_a 遍历版本文件夹并在 script_b 上运行测试脚本。在每次迭代中,都会将一个子文件夹添加到导入路径中,因此测试脚本将找到相应的 script_b。路径在迭代后被移除。
如果sys.modules已经包含一个版本的 test_script,

# script_a
import sys
import os
import importlib

folders = ['version_1', 'version_2', 'version_3']
folders = [os.getcwd() + '/' + folder for folder in folders]

for folder in folders:
    sys.path.append(folder)


    if 'test_script' in sys.modules:
        importlib.reload(sys.modules['test_script'])
    else:
        importlib.import_module('test_script')

    sys.path.remove(folder)

问题
似乎reload对 test_script 导入的 script_b 没有影响。因此,尽管我将导入路径更改为不同的子文件夹 test_script 始终在版本 1 上运行。如何让 test_script 使用不同版本的 script_b 而不改变 test_script 本身?

跟进:虽然回答了最初的问题,但我想知道,从设计的角度来看,这个解决方案如何?有没有更好/更优雅的方法来自动化这个测试过程?
根据我的发现,重新加载模块并不是一种好的做法。

4

1 回答 1

1

写问题的时候想通了。希望有一天它会帮助某人

即使您无法更改 test_script(或 script_b),也有解决方法。
因为如果相关模块已经导入,import 语句什么都不做,我们可以直接在 script_a 中从我们想要的路径重新加载 script_b。由于在 test_script 中的 import 语句中将其替换为新版本,sys.modules因此不会有任何问题。

更新代码:

# script_a
import sys
import os
import importlib

folders = ['version_1', 'version_2', 'version_3']
folders = [os.getcwd() + '/' + folder for folder in folders]

for folder in folders:
    sys.path.append(folder)

    if 'test_script' in sys.modules:
        importlib.reload(sys.modules['script_b'])      # this line added
        importlib.reload(sys.modules['test_script'])
    else:
        importlib.import_module('test_script')

    sys.path.remove(folder)
于 2017-11-14T23:30:23.393 回答