如何从子目录运行 Python 脚本?

Bla*_*g23 6 python directory terminal import module

我希望能够编写这样的一行代码并让它顺利运行:

python /path/to/python_file.py -arg1 -arg2 -etc
Run Code Online (Sandbox Code Playgroud)

我找到了一种发现所有模块并将它们添加到当前 Python 路径的简单方法,但它似乎仍然无法识别 .py 文件,即使它应该在 .py 文件中sys.path。我知道sys.path添加是有效的,因为我可以在解释器中很好地执行此操作:

>>>import ModuleManager # My Python script to discover modules in lower directories
>>>import testModule # Module I want to run from lower directory
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named testModule

>>>ModuleManager.discoverModules() # Now, I find the modules and add them to path
Discovering Modules...Complete!
Discovered 6 Modules.
>>>import testModule # No error now.
>>>
Run Code Online (Sandbox Code Playgroud)

此时我想做的是能够进入我的终端并说:

python testModule -arg1 -arg2 -etc
Run Code Online (Sandbox Code Playgroud)

并让它按照我的预期执行。

明确地说,我想在ModuleManager.py(从我的应用程序根文件夹)中编写一行代码,允许我访问一个名为的文件testModule.py,该文件以/root/path/to/testModule.py某种方式找到,以便我可以使用python testModule.py -arg1 -arg2 -etc. 有什么建议?

Jan*_*sky 7

如何高效编写python脚本

有多种方法可以编写 Python 脚本(一个脚本,应该从命令行调用)。

为了灵活使用,忘记操纵PYTHONPATH- 这样的解决方案难以维护并且相当不稳定。

仅使用 Python stdlib 导入的脚本

完全依赖包和模块,它们是 Python stdlib 的一部分,使脚本可以轻松地从任何地方运行。

对此的扩展是导入全局安装的模块和包。全局安装包通常被认为是不好的做法,因为它破坏了全局 Python 环境。我在全球范围内只安装了一小部分软件包,我经常使用它们:pyyaml, docopt, lxml, jinja2.

脚本导入任何已安装的包

包和模块,甚至你自己的,都可以通过setup.py. 我花了一段时间才习惯这个,我最初忽略了这个setup.py太复杂的解决方案,但后来我习惯将它用于任何需要导入到我的程序中的自制包。

将安装的包导入到 virtualenv

这是迄今为止我最流行的解决方案。

您将需要您的包裹具有setup.py.

创建 virtualenv 后,您使用 pip来安装您需要的所有软件包。

随着给定的 virtualenv 处于活动状态,您不仅可以简单地使用脚本,无论您的脚本从哪里开始,它都会看到可用于导入的包。

通过以下方式安装的脚本 setup.py

同样,这个解决方案首先看起来过于复杂“只是为了简单的脚本”,但最终它可以成为最简单的方法。

您必须setup.py仅使用脚本创建简单的 Python 项目。本setup.py应申报安装脚本。有两种方法,要么通过scripts参数,要么通过entry_points,稍后一种更灵活 - 使用那个。

该脚本最好从 virtualenv 中安装 - 安装完成后,找到脚本的位置并在您想使用它时移动它。使用脚本,不需要激活virtualenv,在PATH中有它就足够了。里面的脚本包括从给定的 virtualenv 对 Python 的引用,这确保它使用它,包括所有已安装的包。

请注意,为您的脚本安装所需软件包的最佳解决方案是在 中的install_requires参数中提及它setup.py,它确保它们会自动与您的脚本一起安装。

使用 zc.buildout

zc.buildout曾经是我最喜欢的解决方案,直到pipvirtualenv成为成熟的解决方案。

您必须创建buildout.cfg文件,然后在那里定义脚本所需的所有内容。这个 moslty 包括有setup.py到位,但这并不总是必要的。

就个人而言,我发现zc.buildout功能强大,但很难学习,我建议使用virtualenv解决方案。

使用其他解决方案,如 PyInstaller

还有其他解决方案,可以将 Python 脚本转换为单个可执行文件。

PyInstaller看起来不错。可能还有其他类似的解决方案。

结论

忘记通过操作使您的模块和包可导入PYTHONPATH,这样的解决方案非常不稳定。

我的建议是去setup.py使用entry_points安装脚本的项目。

安装到 virtualenv 似乎是最干净的方法。

第一次设置这个环境(项目)需要一些努力,但是之后,您可以简单地复制和采用解决方案,这将成为自然而然的方式。


小智 7

sys.path.append(os.getcwd())为我工作。现在你可以运行像这样的命令./manage/my_cli_command.py


Jan*_*sky 5

如何从 Python 调用另一个 Python 脚本

你想调用一个 Python 脚本,它只有在从特定目录运行时才能很好地工作,因为它有一些只能从给定位置正常工作的导入。

假设有一个名为“script_dir”的子目录,并且有一个“local_script_name.py”文件:

import subprocess
subprocess.call(["python", "local_script_name.py"], cwd="script_dir")
Run Code Online (Sandbox Code Playgroud)

如果您的脚本接受命令行参数“arg1”、“arg2”、“-etc”

import subprocess
subprocess.call(["python", "local_script_name.py", "arg1", "arg2", "-etc"], cwd="script_dir")
Run Code Online (Sandbox Code Playgroud)