sys.stdout.write和print之间的区别?


375

在某些情况下 sys.stdout.write()更好的print

示例:更好的性能;更有意义的代码)


4
哪个版本的Python?2.x或3.x?
Mark Byers

老实说,尽管我没有使用Python 3的经验,但我想两者都知道。更新了问题。
Johanna Larsson'7

17
@ S.Lott:询问sys.stdout.write()和之间print(和/或Python为什么同时拥有两者)的基本区别是一个完全合理的问题,不需要示例。OP并未说命令语法令人困惑。
smci 2015年

Answers:


293

print只是一个薄包装器,用于格式化输入(可修改,但默认情况下在args和换行符之间使用空格),并调用给定对象的write函数。默认情况下,此对象为sys.stdout,但是您可以使用“雪佛龙”格式传递文件。例如:

print >> open('file.txt', 'w'), 'Hello', 'World', 2+3

参见:https : //docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement


在Python 3.x中,print成为一个功能,但它仍然有可能通过比其他一些sys.stdout感谢file的说法。

print('Hello', 'World', 2+3, file=open('file.txt', 'w'))

参见https://docs.python.org/3/library/functions.html#print


在Python 2.6+中,print它仍然是一条语句,但可以将其用作

from __future__ import print_function

更新:Bakuriu指出要指出,print函数和print语句之间(并且更一般地,函数和语句之间)存在很小的差异。

评估参数时出现错误:

print "something", 1/0, "other" #prints only something because 1/0 raise an Exception

print("something", 1/0, "other") #doesn't print anything. The function is not called

64
还值得注意的是,它print还会在您编写的任何内容后添加一个换行符,而这不会发生sys.stdout.write
Michael Mior 2010年

5
sys.stdout.write如果您需要编写双版本代码(例如,可与Python 2.x和Python 3.x同时使用的代码),它也更加通用。
andreb 2010年

3
@MichaelMior您可以取消在print末尾加上逗号的换行符:print "this",; print "on the same line as this"
drevicko 2014年

1
@ bjd2385这里>>不是rshift运算符,而是print语句的特定“雪佛龙”形式。参见docs.python.org/2/reference/…–
luc

5
sys.stdout.write()还可以缓冲输入,并且可能不会立即将输入刷新到fd。为了确保它的行为类似于打印功能,您应该添加: sys.stdout.flush()
kerbelp

151

print首先将对象转换为字符串(如果还不是字符串)。如果它不是行的开头,而不是换行符,它将在对象之前放置一个空格。

使用时 stdout,您需要自己将对象转换为字符串(例如,通过调用“ str”),并且没有换行符。

所以

print 99

等效于:

import sys
sys.stdout.write(str(99) + '\n')

32
+1代表换行符!我想说,这是print和之间的主要区别.write()
Eric O Lebigot

9
注意:print可以省略换行符。在Python 2.x中,将逗号放在最后,然后将输出一个空格字符,但不输出换行符。例如,print 99,在Python 3中,print(..., end='')除非您这样做,否则将避免添加换行符(也避免添加空间end=' '。)
ToolmakerSteve 2013年

40
@EOL那真是有趣,一个叫EOL的人发表关于'\ n'的评论……让我发笑。我没有生命 杀我。
Depado 2015年

2
并非如此,print操作在python2.X中的信号处理程序中的行为略有不同,即在示例中无法用sys.stdout替换print:stackoverflow.com/questions/10777610/…–
ddzialak

41

我的问题是,是否存在 sys.stdout.write()print

前几天完成脚本开发后,我将其上传到了UNIX服务器。我所有的调试消息都使用了print语句,但这些语句出现在服务器日志中。

在这种情况下,您可能需要sys.stdout.write代替。


8
?? 您确定这是print()和之间的区别sys.stdout.write(),而不是stdout和之间的区别stderr吗?为了进行调试,您应该使用logging模块,该模块将消息打印到stderr
ostrokach '16

1
嗯 使用nohup和重定向到.out文件也是如此。
conner.xyz 2016年

1
使用sys.stdout.flush()会有所帮助。
suprit chaudhary

如果您使用nohup,则默认情况下,所有写入都将被重定向到,而无论您使用还是stdoutstderr都将被重定向到。nohup.outprintstdout.write
郑刘

40

这是基于Mark Lutz 的《Learning Python》一书的一些示例代码,它解决了您的问题:

import sys
temp = sys.stdout                 # store original stdout object for later
sys.stdout = open('log.txt', 'w') # redirect all prints to this log file
print("testing123")               # nothing appears at interactive prompt
print("another line")             # again nothing appears. it's written to log file instead
sys.stdout.close()                # ordinary file object
sys.stdout = temp                 # restore print commands to interactive prompt
print("back to normal")           # this shows up in the interactive prompt

在文本编辑器中打开log.txt将显示以下内容:

testing123
another line

有什么方法可以使我打印到屏幕以及写入文件吗?
Devesh Saini 2014年

5
@DeveshSaini:是的,只需使用至少具有write()和flush()函数的代理类覆盖sys.stdout。我在这里写了一个示例片段。
2014年

14

至少有一种情况需要sys.stdout打印而不是打印。

如果您想覆盖一行而不转到下一行,例如在绘制进度条或状态消息时,则需要遍历以下内容

Note carriage return-> "\rMy Status Message: %s" % progress

而且由于print添加了换行符,因此最好使用sys.stdout


2
如果print添加了新行,为什么不只打印print('message',end ='')?
Apoorv Patne

8

我的问题是,是否存在sys.stdout.write()print

如果您正在编写一个可以同时写入文件和stdout的命令行应用程序,那么它将非常方便。您可以执行以下操作:

def myfunc(outfile=None):
    if outfile is None:
        out = sys.stdout
    else:
        out = open(outfile, 'w')
    try:
        # do some stuff
        out.write(mytext + '\n')
        # ...
    finally:
        if outfile is not None:
            out.close()

这确实意味着您无法使用该with open(outfile, 'w') as out:模式,但有时值得。


严格来说,您可以使用with- def process(output): # .../ if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)(当然在必要时添加换行符)。当然,那不是很干净。
基金莫妮卡的诉讼

4

在2.x中,该print语句将对您提供的内容进行预处理,将其转换为字符串,处理分隔符和换行符,并允许重定向至文件。3.x将其转换为功能,但仍具有相同的职责。

sys.stdout 是一个文件或类似文件的文件,具有用于写入文件的方法,该方法沿该行使用字符串或其他内容。


3

当动态打印很有用时,例如在较长的过程中提供信息,则最好:

import time, sys
Iterations = 555
for k in range(Iterations+1):
    # some code to execute here ...
    percentage = k / Iterations
    time_msg = "\rRunning Progress at {0:.2%} ".format(percentage)
    sys.stdout.write(time_msg)
    sys.stdout.flush()
    time.sleep(0.01)

2
用print(time_msg,end ='')代替sys.stdout.write(time_msg)sys.stdout.flush()也可以工作
6

2
>>> sys.stdout.write(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a string or other character buffer object
>>> sys.stdout.write("a")
a>>> sys.stdout.write("a") ; print(1)
a1

观察上面的示例:

  1. sys.stdout.write不会写非字符串对象,但是print

  2. sys.stdout.write不会在结尾处添加一个新行标志,但print

如果我们深入潜水,

sys.stdout 是一个文件对象,可用于输出print()

如果print()未指定的文件参数,sys.stdout则将使用


1

在某些情况下,sys.stdout.write()更适合打印吗?

例如,我正在研究一个小的函数,该函数在将数字作为参数传递时以金字塔格式打印星星,尽管您可以使用end =“”在单独的行中打印来完成此操作,但我使用sys.stdout.write来进行协调与印刷使这项工作。要详细说明此stdout.write,请在同一行中打印,因为print总是在单独的行中打印其内容。

import sys

def printstars(count):

    if count >= 1:
        i = 1
        while (i <= count):
            x=0
            while(x<i):
                sys.stdout.write('*')
                x = x+1
            print('')
            i=i+1

printstars(5)

1

在某些情况下,sys.stdout.write()更适合打印吗?

我发现在多线程情况下stdout比打印效果更好。我使用队列(FIFO)存储要打印的行,并且在打印行之前保留所有线程,直到我的打印Q为空。即使这样,使用print有时也会在调试I / O上丢失最后的\ n(使用wing pro IDE)。

当我在字符串中使用\ n的std.out时,调试I / O格式正确,并且\ n正确显示。


您是否知道在这种情况下stdout应该比打印更好的原因,或者这是轶事?您能提供一个发生这种情况的最小工作示例吗?
user2653663

我的想法是stdout的工作水平比print低。我肯定有线程损坏,因为两个打印例程正在争相通过stdout进行馈送。从每个线程向stdout一个写操作为我消除了损坏。
David Poundall '18


1

在Python 3中,有使用print over的正当理由sys.stdout.write,但是这个原因也可以转化为使用原因sys.stdout.write

这是因为,现在print是Python 3中的一个函数,您可以重写它。因此,您可以在简单的脚本中的任何地方使用print,并确定需要写入的那些print语句stderr。现在,您可以重新定义打印功能,甚至可以通过使用内置模块来更改打印功能来全局更改它。当然,file.write您可以指定什么文件,但是通过覆盖打印,您还可以重新定义行分隔符或参数分隔符。

另一种方法是。也许您绝对确定要写信给stdout,但也知道要将print更改为其他内容,可以决定使用sys.stdout.write,并将print用于错误日志或其他内容。

因此,您使用什么取决于您打算如何使用它。print更加灵活,但这可能是使用和不使用它的原因。我仍然会选择灵活性,然后选择打印。print代替使用的另一个原因是熟悉度。现在,更多的人会通过印刷品了解您的意思,而很少了解sys.stdout.write


1

尝试将字节打印成十六进制外观时,以下区别之一是。例如,我们知道,十进制值的2550xFF十六进制的外观:

val = '{:02x}'.format(255) 

sys.stdout.write(val) # prints ff2
print(val)            # prints ff

那不是这个。它只会在交互式外壳中发生,并且因为... write()未添加\n和返回(以及交互式外壳显示)函数的返回值(写入的字符数),十六进制表示形式或所显示的任何其他内容都不重要。
Ondrej K.

0

在python 2中,如果您需要传递函数,则可以将os.sys.stdout.write分配给变量,则不能(在repl中)使用print进行此操作。

>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>> 

那按预期工作。

>>> cmd=print
  File "<stdin>", line 1
    cmd=print
            ^
SyntaxError: invalid syntax

那行不通。打印是一种神奇的功能。


0

在Python 3中要指出的print和之间的区别sys.stdout.write也是在终端中执行时返回的值。在Python 3中,sys.stdout.write返回字符串的长度,而print仅返回None

因此,例如,在终端中以交互方式运行以下代码将打印出字符串,然后打印其长度,因为在交互运行时将返回并输出长度:

>>> sys.stdout.write(" hi ")
 hi 4
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.