我想在我的代码中执行另一个python文件,所以我使用此代码,效果很好:
runner.py
with open(pyfile, encoding="utf-8") as f:
code = f.read()
gl = globals()
gl["__name__"] = "__main__"
gl["__file__"] = pyfile
exec(compile(code, pyfile, 'exec'), gl)
所以我可以用a.py
执行if __name__ in __main__
中的代码:
a.py
def testprint():
print(123321)
if __name__ == "__main__":
testprint()
在runner.py
中,我更改了__file__
和__name__
以确保何时执行a.py
中的runner.py
,就像我在使用{{ 1}}来运行它。
这似乎很好,直到我使用python a.py
获得一个python文件,像这样:
b.py
unittest
当我尝试在import unittest
class Test(unittest.TestCase):
def setUp(self):
pass
def test_case1(self):
pass
def tearDown(self):
pass
if __name__ == '__main__':
unittest.main()
中运行b.py时,它将失败:
runner.py
此问题是因为在单元测试中,它将使用 File "runner.py", line 72, in run_pyfile
exec(compile(code, pyfile, 'exec'), gl)
File "a.py", line 23, in <module>
unittest.main()
File "C:\Python36\Lib\unittest\main.py", line 96, in __init__
self.parseArgs(argv)
File "C:\Python36\Lib\unittest\main.py", line 143, in parseArgs
self.createTests()
File "C:\Python36\Lib\unittest\main.py", line 147, in createTests
self.test = self.testLoader.loadTestsFromModule(self.module)
File "C:\Python36\Lib\unittest\loader.py", line 123, in loadTestsFromModule
tests.append(self.loadTestsFromTestCase(obj))
File "C:\Python36\Lib\unittest\loader.py", line 92, in loadTestsFromTestCase
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
File "C:\Python36\Lib\unittest\suite.py", line 24, in __init__
for test in tests:
TypeError: __init__() takes 1 positional argument but 2 were given
来初始化__main__
,但是它将TestProgram
用作runner.py
,而不是真实的文件路径( b.py)
__main__
-
我尝试了这些方法,但是它们不起作用:
class TestProgram(object):
def __init__(self, module='__main__', defaultTest=None, argv=None,
testRunner=None, testLoader=loader.defaultTestLoader,
exit=True, verbosity=1, failfast=None, catchbreak=None,
buffer=None, warnings=None, *, tb_locals=False):
if isinstance(module, str):
self.module = __import__(module) # <---the result is self.module= runner.py, not b.py
当我使用a.py时,它仍然可以正常工作,但在b.py中却失败了。因为它将把一些奇怪的argv传递给unittest(不是b.py的路径,而是我的python.exe的路径和一些奇怪的数字)
import importlib.util
spec = importlib.util.spec_from_file_location("__main__", "a.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
我可以得到一个字典和一些输出(一些版权的东西),但不是我想要的。
那么如何在代码中执行import runpy
runpy.run_path("a.py")
python文件?
我正在使用Python3.6 +