【问题标题】:When to run external commands in Python何时在 Python 中运行外部命令
【发布时间】:2025-12-16 17:20:04
【问题描述】:

在 Python 中,可以运行 bash 命令来实现可以通过运行等效的 Python 代码来实现的目标。举个简单的例子,将cd 放入目录并做一些事情,你可以这样做:

import subprocess
subprocess.run('cd directory and do other stuff')

import os
os.chdir(path) # path is the path to the directory
#do other stuff

那么你如何选择使用哪一个(我的意思是一般来说,而不是这个简化的例子)?

【问题讨论】:

    标签: python bash command


    【解决方案1】:

    第一个版本只是改变了子进程的目录。它对原始的 Python 进程没有影响,因此它实际上是无用的。只有当它是多个命令的一部分时才值得:

    subprocess.run('cd directory; cat filename', shell=True)
    

    第二个版本改变了Python进程本身的目录。

    更一般地说,如果有一个 Python 函数与外部命令做同样的事情,你应该更喜欢这个函数。它更高效,因为它不必启动新进程,如果您使用shell=True,它不必解析命令,并且您可以获得更灵活的错误处理。

    【讨论】:

    • 我要补充一点,您应该经常尝试使用标准库中的函数。保证它们是跨平台的、更清晰易读、更高效,并且如图所示更易于理解
    • 是的,我只是选择了一个简单的例子,但是在运行 Python 代码和 bash 命令来完成某个任务时一般会有什么区别(我会更新我的问题)
    • 一般来说,如果有函数可以做某事,没有理由使用外部命令。
    【解决方案2】:

    尼特。 subprocess.run('cd directory') 只是更改了子进程的目录,然后退出,丢弃了更改的目录上下文。 os.chdir(path) 并不总是发疯,只有 99% 发疯。您最好使用os.pathpathlib 来跟踪目录,而不是在整个程序中更改“当前”的含义。

    运行外部命令有一个优势,尤其是当它们实现您目前没有的功能时。它们还可以帮助并行化您的代码,例如运行外部 grep 并使用其结果。这样做的缺点是添加了外部平台依赖项。

    这通常只是因为程序员碰巧比 python 更了解 shell。或者在网上找到了一个shell示例。这对于业余爱好者而不是专业代码库来说很好。

    免责声明:恕我直言

    【讨论】:

    • 坦率地说,将os.chdir 称为“99% 疯狂”是荒谬的。
    • @chepner - 好的,98%。那是两倍好!从用户的角度来看,“当前目录”是启动命令时用户所在的目录。用户可以合理地期望相对路径相对于他的 cwd。但是对于 GUI 和任何可能从配置文件或环境变量,甚至是 GUI 对话框获取路径的东西,相对于这些变量使用 os.pathpathlib 是更好的路径。我很难想到我遇到的一个案例,os.chdir 是个好主意。
    • 我很难想出一个很好的理由来假设用户的主目录将是程序的当前工作目录。如果你想做出这样的假设,以os.chdir(os.environ["HOME"]) 开始你的程序将是确保这一点的一种方法。
    • @chepner - 相反,散布在您的代码周围的os.chdir 几乎肯定是调试的噩梦。 "foo/bar/baz.txt" 以前可以用,为什么现在不行?
    • @chepnet - 我很难想出一个理由来假设用户的主目录是强制 CWD 的一个很好的候选者,而不管程序的初始点是在哪里启动的。正如您所说,“HOME”适用于您的代码需要的任何基于主目录的内容。无需chdir
    【解决方案3】:

    我不会选择前者。它创建一个子进程并更改该子进程内的目录,然后终止,使 Python 进程的当前目录与 subprocess.run 调用之前相同。

    os.chdir实际上改变了当前进程的工作目录。在您开始使用线程并意识到一个线程的当前目录可能会受到来自另一个线程的 os.chdir 调用的影响之前,这似乎很好。

    对于单线程进程(Ingorant Wandered 通常最初可能会编写的那种),这没有问题。

    更广泛地说,如果您需要比 Python 单独提供的更多并行性,则可以使用 subprocess 模块(研究“Python GIL”以找出为什么简单的 Python 进程只能使用多核计算机的一个内核)。

    【讨论】:

    • 有趣。我实际上正在研究一个多线程代码示例!感谢您指出它有帮助
    最近更新 更多