简体   繁体   English

何时在 Python 中运行外部命令

[英]When to run external commands in Python

In Python, it's possible to run a bash command to achieve something that can be achieved by running equivalent Python code.在 Python 中,可以运行 bash 命令来实现可以通过运行等效的 Python 代码来实现的目标。 As a simple example, to cd into a directory and do stuff, you could do either:作为一个简单的例子,要cd进入一个目录并做一些事情,你可以这样做:

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

or或者

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

So how do you choose which one to use (I mean in general, not with this simplified example)?那么你如何选择使用哪一个(我的意思是一般来说,而不是这个简化的例子)?

The first version just changes the directory of the subprocess.第一个版本只是更改了子进程的目录。 It has no effect on the original Python process, so it's practically useless.它对原来的Python工艺没有影响,所以实际上没用。 It would only be worthwhile if it were part of multiple commands:只有当它是多个命令的一部分时才值得:

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

The second version changes the directory of the Python process itself.第二个版本更改了 Python 进程本身的目录。

More generally, if there'a Python function that does the same thing as an external command, you should prefer the function.更一般地说,如果有一个 Python function 与外部命令执行相同的操作,您应该更喜欢 function。 It's more efficient since it doesn't have to start a new process, it doesn't have to parse the command if you use shell=True , and you get more flexible error handling.它更高效,因为它不必启动新进程,如果使用shell=True则不必解析命令,并且您可以获得更灵活的错误处理。

I wouldn't choose the former.我不会选择前者。 It creates a subprocess and changes to the directory inside that subprocess, which then terminates leaving the Python process's current directory the same as it was before the subprocess.run call.它创建一个子进程并更改该子进程内的目录,然后终止使 Python 进程的当前目录与调用subprocess.run之前相同。

os.chdir actually changes the working directory of the current process. os.chdir实际上改变了当前进程的工作目录。 Which seems fine until you start using threads and realise that one thread's current directory can be affected by an os.chdir call from another thread.在您开始使用线程并意识到一个线程的当前目录可能会受到来自另一个线程的os.chdir调用的影响之前,这似乎很好。

For single-threaded processes (the kind an Ingorant Wandered might typically write initially) this presents no problems.对于单线程进程(Ingorant Wandered 通常最初可能会编写的那种),这没有问题。

More broadly, expect to use the subprocess module if you need more parallelism than Python can provide alone (research "Python GIL" to find out why naive Python processes can only use one core of a multicore computer).更广泛地说,如果您需要比 Python 单独提供的更多并行性,则期望使用subprocess模块(研究“Python GIL”以找出为什么幼稚的 Python 进程只能使用多核计算机的一个核心)。

Niether.尼特。 subprocess.run('cd directory') just changed the directory of the subprocess which then exited, discarding that changed-directory context. subprocess.run('cd directory')只是更改了子进程的目录,然后退出,丢弃了更改的目录上下文。 os.chdir(path) is not always insane, just 99% insane. os.chdir(path)并不总是疯狂的,只有 99% 的疯狂。 You are better off using os.path or pathlib to track directories and not changing what "current" means throughout the program.您最好使用os.pathpathlib来跟踪目录,而不是在整个程序中更改“当前”的含义。

There is an advantage to running external commands, especially if they implement functionality you don't have at the moment.运行外部命令有一个优势,特别是如果它们实现了您目前没有的功能。 They can also help parallelize your code such as running an external grep and using its results.它们还可以帮助您并行化您的代码,例如运行外部grep并使用其结果。 That has the disadvantage of adding external platform dependencies.这具有添加外部平台依赖项的缺点。

Frequently its only because the programmer happened to understand the shell better than python.通常只是因为程序员碰巧比 python 更了解 shell。 Or found a shell example on the net.或者在网上找到了一个 shell 的例子。 That's fine for a hobbyist not not a professional code base.这对于业余爱好者而不是专业代码库来说很好。

Disclaimer: IMHO免责声明:恕我直言

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM