有几种方法可以写入stderr:

print >> sys.stderr, "spam"  # Python 2 only.

sys.stderr.write("spam\n")

os.write(2, b"spam\n")

from __future__ import print_function
print("spam", file=sys.stderr)

这些方法之间有什么区别?应首选哪种方法?


当前回答

EDIT在事后看来,我认为更改sys.stderr和没有看到行为更新可能会产生混淆,这使得这个答案不如其他人指出的那样简单。

使用partial只会节省1行代码。潜在的混淆不值得保存一行代码。

起初的

为了更简单,这里有一个使用“partial”的版本,这对包装函数有很大帮助。

from __future__ import print_function
import sys
from functools import partial

error = partial(print, file=sys.stderr)

然后你就这样使用它

error('An error occured!')

您可以通过执行以下操作(从http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off-stdout-and.html):

# over-ride stderr to prove that this function works.
class NullDevice():
    def write(self, s):
        pass
sys.stderr = NullDevice()

# we must import print error AFTER we've removed the null device because
# it has been assigned and will not be re-evaluated.
# assume error function is in print_error.py
from print_error import error

# no message should be printed
error("You won't see this error!")

这样做的缺点是在创建时将sys.stderr的值部分分配给包装函数。这意味着,如果稍后重定向stderr,则不会影响此函数。如果您计划重定向stderr,请使用aaguirre在本页中提到的**kwargs方法。

其他回答

我发现这是唯一一个简短、灵活、便携和可读的:

import sys

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

可选函数eprint可以节省一些重复。它可以以与标准打印功能相同的方式使用:

>>> print("Test")
Test
>>> eprint("Test")
Test
>>> eprint("foo", "bar", "baz", sep="---")
foo---bar---baz

这将模拟标准打印函数,但输出到stderr

def print_err(*args):
    sys.stderr.write(' '.join(map(str,args)) + '\n')

还没有人提到日志记录,但日志记录是专门为传递错误消息而创建的。基本配置将设置写入stderr的流处理程序。

此脚本:

# foo.py
import logging

logging.basicConfig(format='%(message)s')
log = logging.getLogger(__name__)
log.warning('I print to stderr by default')
print('hello world')

在命令行上运行时具有以下结果:

$ python3 foo.py > bar.txt
I print to stderr by default

bar.txt将包含打印在stdout上的“helloworld”。

我在python 3.4.3中工作。我正在减少一点打字,显示我是如何来到这里的:

[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ python3
>>> import sys
>>> print("testing", file=sys.stderr)
testing
>>>
[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ 

它起作用了吗?尝试将stderr重定向到一个文件,看看会发生什么:

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ python3 2> /tmp/test.txt
>>> import sys
>>> print("testing", file=sys.stderr)
>>> [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$
[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ cat /tmp/test.txt
Python 3.4.3 (default, May  5 2015, 17:58:45)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
testing

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$

好吧,除了python给你的小介绍已经被插入stderr(它还会去哪里?)之外,它还是有效的。

如果由于严重错误而要退出程序,请使用:

sys.exit("Your program caused a fatal error. ... description ...")

并在标头中导入sys。