xlabel位置 - 如何在Python中打印stderr?




python画图label (10)

问题的答案是:在python中打印stderr有不同的方法,但依赖于1)我们使用的是哪个python版本2)我们想要的确切输出。

print和stderr的写函数之间的区别: stderr :stderr(标准错误)是内置于每个UNIX / Linux系统中的管道,当程序崩溃并打印出调试信息时(如Python中的回溯),它会进入stderr管。

print :print是一个封装器,用于格式化输入(输入是参数和末尾换行符之间的空格),然后调用给定对象的写入函数,默认情况下给定的对象是sys.stdout,但我们可以传递文件即我们也可以在文件中打印输入。

Python2:如果我们使用python2的话

>>> import sys
>>> print "hi"
hi
>>> print("hi")
hi
>>> print >> sys.stderr.write("hi")
hi

在Python3中,Python2尾随逗号变成了一个参数,所以如果我们在打印后使用尾随逗号以避免换行符,这将在Python3中看起来像print('Text to print',end =''),这是Python2下的语法错误。

http://python3porting.com/noconv.html

如果我们在python3中检查上面的sceario:

>>> import sys
>>> print("hi")
hi

在Python 2.6下, 将来可以导入打印到一个函数中。 因此,为了避免任何语法错误和其他差异,我们应该在将来导入print_function时使用print()来启动任何文件。 未来的导入只适用于Python 2.6及更高版本,因此对于Python 2.5及更早版本,您有两种选择。 您可以将更复杂的打印转换为更简单的打印,也可以使用可在Python2和Python3下使用的单独打印功能。

>>> from __future__ import print_function
>>> 
>>> def printex(*args, **kwargs):
...     print(*args, file=sys.stderr, **kwargs)
... 
>>> printex("hii")
hii
>>>

案例:需要注意的是,sys.stderr.write()或sys.stdout.write()(stdout(标准输出)是内置于每个UNIX / Linux系统中的管道)不能取代打印,但是在某些情况下,我们可以使用它作为替代。 Print是一个封装器,它在最后用空格和换行符封装输入,并使用写入函数进行写入。 这就是sys.stderr.write()更快的原因。

注意:我们也可以使用Logging跟踪和调试

#test.py
import logging
logging.info('This is the existing protocol.')
FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)

https://docs.python.org/2/library/logging.html#logger-objects

我遇到过至少三种打印到stderr的方法:

 import sys

 print >> sys.stderr, 'spam'

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

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

这似乎与Python#13 †的 禅宗相矛盾,所以最好的方法是什么? 这种方式或其他方式有什么优点或缺点吗?

应该有一个 - 而且最好只有一个 - 明显的方法来做到这一点。


print >> sys.stderr已经在Python3中消失了。 http://docs.python.org/3.0/whatsnew/3.0.html说:

Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)

不幸的是,这很难看。 或者,使用

sys.stderr.write("fatal error\n")

但请注意, write不是1:1的print替换。


编辑在后视中,我认为可能与sys.stderr的变化相混淆,并且没有看到更新的行为,这使得这个答案不如其他人指出的那样使用简单的函数。

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

原版的

为了使它更容易,这里有一个使用'partial'的版本,这对于包装函数是一个很大的帮助。

from __future__ import print_function
import sys
from functools import partial

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

然后你就这样使用它

error('An error occured!')

您可以通过执行以下操作来检查它是否打印到stderr而不是stdout(来自http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off-stdout-and.html的优先代码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 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倍!


尝试:

from sys import stderr


print >> sys.stderr, 'spam' 

我会说你的第一个方法:

print >> sys.stderr, 'spam' 

是“一个...... 明显的做法”其他人不满足规则1(“美丽胜于丑陋”)。


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

from __future__ import print_function
import sys

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

eprint功能可以像标准print功能一样使用:

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

我在Python 3.4.3中工作。 我正在削减一些打字,这表明我是如何到达这里的:

[18:19 [email protected] pexpect]$ python3
>>> import sys
>>> print("testing", file=sys.stderr)
testing
>>>
[18:19 [email protected] pexpect]$ 

它有用吗? 尝试将stderr重定向到文件并查看会发生什么情况:

[18:22 [email protected] pexpect]$ python3 2> /tmp/test.txt
>>> import sys
>>> print("testing", file=sys.stderr)
>>> [18:22 [email protected] pexpect]$
[18:22 [email protected] 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 [email protected] pexpect]$

那么,除了python给你的小小介绍已被嘲讽为stderr(还有其他什么地方会去?)之外,它的工作原理。


这同样适用于stdout:

print 'spam'
sys.stdout.write('spam\n')

正如其他答案中所述, print提供了一个非常方便的界面(例如,用于打印调试信息),而写入速度更快,并且在必须以特定方式精确格式化输出时也更方便。 我也会考虑可维护性:

  1. 您稍后可能决定在stdout / stderr和常规文件之间切换。

  2. 在Python 3中, print()语法已经改变,所以如果你需要支持两个版本, write()可能会更好。


这将模仿标准的打印功能,但输出在stderr上

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




zen