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

时间:2014-07-15 18:55:27

标签: python import module terminal directory

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

python /path/to/python_file.py -arg1 -arg2 -etc

我找到了一种简单的方法来发现所有模块并将它们添加到当前的Python路径中,但它似乎仍然无法识别.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.
>>>

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

python testModule -arg1 -arg2 -etc

让它表现我的期望。

要清楚,我想在ModuleManager.py(来自我的应用程序根文件夹)中编写一行代码,允许我访问testModule.py中找到的名为/root/path/to/testModule.py的文件。以某种方式,我可以使用python testModule.py -arg1 -arg2 -etc中的参数。有什么建议吗?

4 个答案:

答案 0 :(得分:3)

sys.path.append(os.getcwd())为我工作。 现在您可以运行./manage/my_cli_command.py

之类的命令

答案 1 :(得分:2)

如何有效地编写python脚本

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

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

仅使用Python stdlib导入的脚本

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

对此的扩展是导入全局安装的模块和包。全局安装包通常被认为是不好的做法,因为它破坏了全球Python环境。我在全球范围内安装了一小组软件包,我经常使用这些软件包:pyyamldocoptlxmljinja2

导入任何已安装软件包的脚本

可以通过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.buildoutpip成为成熟解决方案之前,

virtualenv曾是我最喜欢的解决方案。

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

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

使用其他解决方案,例如PyInstaller

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

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

结论

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

我建议使用setup.py使用entry_points来安装您的脚本。

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

首次设置此环境(项目)需要付出一些努力,但在此之后,您可以简单地复制并采用该解决方案,这将是自然的方式。

答案 2 :(得分:1)

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

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

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

import subprocess
subprocess.call(["python", "local_script_name.py"], cwd="script_dir")

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

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

答案 3 :(得分:0)

将父目录临时附加到路径:

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))