经过对网络的许多研究,在许多不同的主题上,我无法找到解决问题的解决方案。
我正在开发一个工具(带图形界面),允许处理来自不同项目的python脚本。 为了没有任何依赖问题,我要求用户定位项目目录以及要处理的脚本。
因此,为了开发这个工具,我在我的IDE中有一个项目" benchmark_tool"这是集成GUI和项目的项目" test_project"其中包含各种测试脚本。显然,最终目标是要编译的工具,因此项目" benchmark_tool"从IDE中消失。
以下是IDE架构:
benchmark_tool (python project)
__init__.py
main.py
test_project (python project)
__init__.py
module1
__init__.py
test_script.py
module2
__init__.py
imports.py
工作原理:main.py应调用test_script.py。 test_script.py在脚本的第一个初始化时调用imports.py。
更新
我在主代码中尝试了一些修改:
import sys
import subprocess
subprocess.check_call([sys.executable, '-m', 'test_project.module1.test_script'], cwd='D:/project/python')
我收到了这个错误
Traceback(most recent call last):
File "C:/Python31/lib/runpy.py", line 110, in run module as main
mod_name, loader, code, fname = _get_module_detail(mod_name)
File "C:/Python31/lib/runpy.py", line 91, in get module details
code = loader.get_code(mod_name)
File "C:/Python31/lib/pkgutil.py", line 272, in get code
self.code = compile(source, self.filename, 'exec')
File "D:/project/python/test_project/module1/test_script.py", line 474
SyntaxError: invalid syntax
Traceback (most recent call last):
File "D:/other_project/benchmark_tool/main.py", line 187, in read
subprocess.check_call([sys.executable, '-m', 'module1.test_script.py'], cwd='D:/project/python/test_project')
File "C:/Python31/lib/subprocess.py", line 446, in check call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['C:/Python31/python.exe', '-m', 'module1.test_script.py']' returned non-zero exit status 1
注意
它适用于subprocess.Popen(['python','D:/project/python/test_project/module1/test_script.py])
两种方法的主要区别是什么?我还必须将参数传递给test_scripts.py,哪一个最适合用来与python脚本通信(输入和输出数据是否被交换)?
先谢谢
答案 0 :(得分:0)
要运行“外部项目脚本”,请安装它,例如:pip install project
(如果您愿意,可以在virtualenv中运行它),然后像运行任何其他可执行文件一样运行脚本:
#!/usr/bin/env python
import subprocess
subprocess.check_call(['executable', 'arg 1', '2'])
如果您不想安装项目并且它没有依赖项(或者您假设它们已经安装),那么从给定路径作为子进程运行脚本(假设有module1/__init__.py
文件) :
#!/usr/bin/env python
import subprocess
import sys
subprocess.check_call([sys.executable, '-m', 'module1.test_script'],
cwd='/abs/path/to/test_project')
使用-m
运行脚本,避免使用many import issues。
以上假设test_project
不是Python包(无test_project/__init__.py
)。如果test_project
本身就是一个Python包,那么将它包含在模块名称中,然后从父目录开始:
subprocess.check_call([sys.executable, '-m', 'test_project.module1.test_script'],
cwd='/abs/path/to')
您可以将路径作为命令行参数(test_project
)传递到sys.argv
目录,或者从配置文件(configparser
,json
)中读取它。避免相对于父脚本的安装路径计算它(如果必须使用pkgutil
,setuptools'pkg_resources
来获取数据)。要查找存储用户数据的位置,您可以使用appdirs
Python package。
答案 1 :(得分:0)
我发现有3个问题需要修复:
*__init__.py
文件将该目录转换为包test_script.py
时,您需要文件的完整路径,而不仅仅是文件名test_script.py
,请设置PYTHONPATH
环境变量因此,我的解决方案是:
import os
import sys
import subprocess
# Here is one way to determine test_project
# You might want to do it differently
script_dir = os.path.abspath(os.path.dirname(__file__))
test_project = os.path.normpath(os.path.join(script_dir, '..', 'test_project'))
python_path = '{}:{}'.format(os.environ.get('PYTHONPATH', ''), test_project)
python_path = python_path.lstrip(':') # In case PYTHONPATH was not set
# Need to determine the full path to the script
script = os.path.join(test_project, 'module1', 'test_script.py')
proc = subprocess.Popen(['python', script], env=dict(PYTHONPATH=python_path))