有几种方法可以写入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)
这些方法之间有什么区别?应首选哪种方法?
有几种方法可以写入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)
这些方法之间有什么区别?应首选哪种方法?
当前回答
还没有人提到日志记录,但日志记录是专门为传递错误消息而创建的。基本配置将设置写入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”。
其他回答
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方法。
还没有人提到日志记录,但日志记录是专门为传递错误消息而创建的。基本配置将设置写入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”。
我这样做只是为了好玩,但这里有另一种方式…:-)
message = 'error: Belly up!!'
print(message, file=sys.stderr if 'error' in message.lower() else sys.stdout)
如果进行简单测试:
import time
import sys
def run1(runs):
x = 0
cur = time.time()
while x < runs:
x += 1
print >> sys.stderr, 'X'
elapsed = (time.time()-cur)
return elapsed
def run2(runs):
x = 0
cur = time.time()
while x < runs:
x += 1
sys.stderr.write('X\n')
sys.stderr.flush()
elapsed = (time.time()-cur)
return elapsed
def compare(runs):
sum1, sum2 = 0, 0
x = 0
while x < runs:
x += 1
sum1 += run1(runs)
sum2 += run2(runs)
return sum1, sum2
if __name__ == '__main__':
s1, s2 = compare(1000)
print "Using (print >> sys.stderr, 'X'): %s" %(s1)
print "Using (sys.stderr.write('X'),sys.stderr.flush()):%s" %(s2)
print "Ratio: %f" %(float(s1) / float(s2))
你会发现sys.stderr.write()总是快1.81倍!
import sys
sys.stderr.write()
是我的选择,只是更具可读性,更准确地说出您想要做的事情,并且可以跨版本移植。
编辑:在可读性和性能方面,“蟒蛇”是我的第三个想法。。。考虑到这两件事,使用python,80%的代码将是pythonic的。列表理解是不经常使用的“大事”(可读性)。