Check_output()似乎不存在(Python 2.6.5)

我一直在阅读有关子流程模块的 Python 文档(请参阅 给你) ,其中谈到了 subprocess.check_output()命令,这似乎正是我所需要的。

但是,当我尝试使用它时,我得到一个错误,它并不存在,当我运行 dir(subprocess)时,它没有被列出来。

我正在运行 Python 2.6.5,我使用的代码如下:

import subprocess
subprocess.check_output(["ls", "-l", "/dev/null"])

有人知道为什么会这样吗?

57969 次浏览

它是在2.7中引入的,参见 医生

如果需要输出,请使用 子流程,打开:

>>> import subprocess
>>> output = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0]

如果 在你想要运行的代码中大量使用,但是这些代码不需要长期维护(或者你需要一个快速修复,不管未来的维护是否令人头疼) ,那么你可以在任何导入子进程的地方使用它。

把2.7的代码提取出来,这样插入..。

import subprocess


if "check_output" not in dir( subprocess ): # duck punch it in!
def f(*popenargs, **kwargs):
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd)
return output
subprocess.check_output = f

可能需要轻微的坐立不安。

请记住,虽然你的责任是维护这样肮脏的小后端口。如果在最新的 Python 中发现并修正了 bug,那么如果你想保持安全,那么 a)必须注意到这一点,b)更新你的版本。此外,自己重写和定义内部功能是下一个家伙最可怕的噩梦,特别是当下一个家伙是你几年后,你已经忘记了所有的肮脏的黑客你上次!总而言之,这很少是个好主意。

由于猴子修补程序的建议(我的尝试失败了——但是我们正在使用 CalledProcessError 输出,所以需要猴子修补程序)

在这里找到了一个可以工作的2.6补丁: Http://pydoc.net/python/pep8radius/0.9.0/pep8radius.shell/

"""Note: We also monkey-patch subprocess for python 2.6 to
give feature parity with later versions.
"""
try:
from subprocess import STDOUT, check_output, CalledProcessError
except ImportError:  # pragma: no cover
# python 2.6 doesn't include check_output
# monkey patch it in!
import subprocess
STDOUT = subprocess.STDOUT


def check_output(*popenargs, **kwargs):
if 'stdout' in kwargs:  # pragma: no cover
raise ValueError('stdout argument not allowed, '
'it will be overridden.')
process = subprocess.Popen(stdout=subprocess.PIPE,
*popenargs, **kwargs)
output, _ = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd,
output=output)
return output
subprocess.check_output = check_output


# overwrite CalledProcessError due to `output`
# keyword not being available (in 2.6)
class CalledProcessError(Exception):


def __init__(self, returncode, cmd, output=None):
self.returncode = returncode
self.cmd = cmd
self.output = output


def __str__(self):
return "Command '%s' returned non-zero exit status %d" % (
self.cmd, self.returncode)
subprocess.CalledProcessError = CalledProcessError