Python运行时确定要加载哪个模块

时间:2016-05-07 15:00:09

标签: python python-2.7 unit-testing import

我有我的Python unittest脚本,如下所示。它需要一个参数' -a'确定测试用例是否应从foo_PC_A.pyfoo_PC_B.py加载基本模块。我使用shutil.move()将.py文件重命名为foo.py,因此所有测试用例模块(例如tm1.pytm2.py)都可以import foo。虽然这看起来像一个解决方法而不是Pythonic。有没有更好的方法来做到这一点?或者是一个更好的设计,从根本上解决这个问题。

(适用run_all_unittest.py)

if sys.argv[1] = '-a':
  shutil.move('foo_PC_A.py', 'foo.py')
else:
  shutil.move('foo_PC_B.py', 'foo.py')


test_module_list = ['tm1', 'tm2', ...]
for test_module_name in test_module_list:
  test_module = __import__(test_module_name)
  test_suites.append(unittest.TestLoader().loadTestsFromModule(test_module))

alltests = unittest.TestSuite(test_suites)
unittest.TextTestRunner().run(alltests)

if sys.argv[1] = '-a':
  shutil.move('foo.py', 'foo_PC_A.py')
else:
  shutil.move('foo.py', 'foo_PC_B.py')

(适用tm1.py)

from foo import MyTestCase
...

(适用foo_PC_A.py)

import <some module only available on PC A>

class MyTestCase(unittest.TestCase):
...

(适用foo_PC_B.py)

# since the PC A modules are not available on PC B, 
# just call the pre-built executable via subprocess
import subprocess
class MyTestCase(unittest.TestCase):
...
  def test_run(self):
        subprocess.call(...)

1 个答案:

答案 0 :(得分:1)

你可以欺骗Python认为模块已经被加载了。只需动态导入模块并使用sys.modules

D/OpenGLRenderer: endAllActiveAnimators on 0xb7d7e248 (RippleDrawable) with handle 0xb76b0cf0
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
D/cr_Ime: [InputMethodManagerWrapper.java:30] Constructor
W/cr_AwContents: onDetachedFromWindow called when already detached. Ignoring
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: false
I/cr_Ime: ImeThread is not enabled.
W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 18631
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime: [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
D/OpenGLRenderer: endAllActiveAnimators on 0xb7a893f8 (RippleDrawable) with handle 0xb7ec8810
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
D/cr_Ime: [InputMethodManagerWrapper.java:30] Constructor
W/cr_AwContents: onDetachedFromWindow called when already detached. Ignoring
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: false
I/cr_Ime: ImeThread is not enabled.
W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 18631
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime: [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow

当任何模块运行import sys import importlib if sys.argv[1] = '-a': sys.modules['foo'] = importlib.import_module('foo_PC_A') else: sys.modules['foo'] = importlib.import_module('foo_PC_A') import foo时,Python将使用该路径。

请注意,如果将from foo import ...移动到包中,则必须指定完整的Python路径,如:

foo