sys.stdout.write 和 print 的区别?
Posted
技术标签:
【中文标题】sys.stdout.write 和 print 的区别?【英文标题】:The difference between sys.stdout.write and print? 【发布时间】:2011-03-16 20:58:55 【问题描述】:是否存在sys.stdout.write()
优于print
的情况?
(示例:更好的性能;更有意义的代码)
【问题讨论】:
哪个版本的 Python? 2.x 还是 3.x? 老实说,我想知道两者,虽然我没有使用 Python 3 的经验。更新了问题。 @S.Lott :询问sys.stdout.write()
和print
之间的基本区别(和/或为什么Python 两者都有)是一个完全合理的问题,不需要示例。 OP 没有说命令语法令人困惑。
【参考方案1】:
在 2.x 中,print
语句对您提供的内容进行预处理,将其转换为字符串,处理分隔符和换行符,并允许重定向到文件。 3.x 把它变成了一个函数,但它仍然有同样的职责。
sys.stdout
是一个文件或类似文件,具有写入它的方法,这些方法采用字符串或沿着该行的东西。
【讨论】:
【参考方案2】:print
首先将对象转换为字符串(如果它还不是字符串)。如果它不是行的开头和结尾的换行符,它也会在对象之前放置一个空格。
使用stdout
时,需要自己将对象转成字符串(比如调用“str”),并且没有换行符。
所以
print 99
相当于:
import sys
sys.stdout.write(str(99) + '\n')
【讨论】:
+1 用于提及换行符!这是print
和.write()
之间的主要区别,我想说。
注意:print
可以省略换行符。在 Python 2.x 中,在末尾加一个逗号,会输出一个空格字符,但没有换行符。例如。 print 99,
在 Python 3 中,print(..., end='')
将避免添加换行符(也避免添加空格,除非您使用 end=' '
。
这不是真的,print
操作在 python2.X 中的信号处理程序中的行为略有不同,即在示例中不能用 sys.stdout 替换 print:***.com/questions/10777610/…
为了获得更好的性能,假设print(99)
相当于:sys.stdout.write(str(99));sys.stdout.write('\n')
【参考方案3】:
print
只是一个瘦包装器,用于格式化输入(可修改,但默认情况下,在 args 和换行符之间有一个空格)并调用给定对象的 write 函数。默认情况下,此对象为sys.stdout
,但您可以使用“chevron”形式传递文件。例如:
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
成为一个函数,但由于 file
参数,它仍然可以传递 sys.stdout
以外的其他内容。
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
【讨论】:
另外值得注意的是,print
还会在您编写的任何内容后附加一个换行符,而 sys.stdout.write
不会发生这种情况。
如果您需要编写双版本代码(例如与 Python 2.x 和 Python 3.x 同时工作的代码),sys.stdout.write
也更通用。
@MichaelMior 您可以取消 print
附加一个尾随逗号的换行符:print "this",; print "on the same line as this"
sys.stdout.write()
也会缓冲输入,并且可能不会立即将输入刷新到 fd。为了确保它的行为类似于打印功能,您应该添加:sys.stdout.flush()
您可以使用print(blah, end="")
来防止打印中出现换行符。【参考方案4】:
我的问题是有没有 是这样的情况
sys.stdout.write()
最好
前几天完成脚本开发后,我将它上传到了一个unix服务器。我所有的调试消息都使用了print
语句,并且这些不会出现在服务器日志中。
在这种情况下,您可能需要sys.stdout.write
。
【讨论】:
嗯?您确定这是print()
和sys.stdout.write()
之间的区别,而不是stdout
和stderr
之间的区别吗?对于调试,您应该使用logging
模块,它将消息打印到stderr
。
是的。使用nohup
并重定向到.out
文件也是如此。
使用 sys.stdout.flush() 会有所帮助。
如果你使用nohup
,默认情况下所有写到stdout
和stderr
的都会重定向到nohup.out
,不管你是使用print
还是stdout.write
。
这个答案是推测和误导/错误的,绝对不应该有 40 多个赞成票(在撰写本文时)。【参考方案5】:
以下是基于 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
【讨论】:
有什么方法可以让我打印到屏幕以及写入文件吗? @DeveshSaini:是的,只需使用至少具有 write() 和 flush() 函数的代理类覆盖 sys.stdout。我写了一个例子 sn -p here.【参考方案6】:我的问题是在某些情况下
sys.stdout.write()
比
如果您正在编写一个可以写入文件和标准输出的命令行应用程序,那么它很方便。您可以执行以下操作:
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)
(当然,在必要时添加换行符)。不过,这绝对不是很干净,这是肯定的。【参考方案7】:
至少有一种情况需要sys.stdout
而不是打印。
当你想覆盖一行而不转到下一行时,例如在绘制进度条或状态消息时,你需要循环类似的东西
Note carriage return-> "\rMy Status Message: %s" % progress
而且由于 print 添加了换行符,所以最好使用 sys.stdout
。
【讨论】:
如果 print 添加了一个新行,为什么不直接使用 print('message', end = '') 呢?【参考方案8】:在某些情况下 sys.stdout.write() 是否更可取 打印?
例如,我正在开发一个小函数,它在将数字作为参数传递时以金字塔格式打印星星,尽管您可以使用 end="" 来完成此操作在单独的行中打印,我使用 sys.stdout.write 与 print 配合来完成此操作工作。详细说明此 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)
【讨论】:
【参考方案9】:在哪些情况下 sys.stdout.write() 更适合打印?
我发现在多线程情况下,stdout 比 print 效果更好。我使用队列 (FIFO) 来存储要打印的行,并在打印行之前保留所有线程,直到我的打印队列为空。即便如此,使用 print 我有时会在调试 I/O 上丢失最后的 \n(使用 Wing Pro IDE)。
当我在字符串中使用带有 \n 的 std.out 时,调试 I/O 格式正确并且 \n 被准确显示。
【讨论】:
你知道为什么 stdout 在这种情况下应该比打印更好,或者这是轶事吗?您能否提供一个发生这种情况的最小工作示例? 我的想法是标准输出的工作水平低于打印。我肯定有线程损坏,因为两个打印例程正在争夺通过标准输出。从每个线程写入一个标准输出为我消除了损坏。 ***.com/questions/7877850/…【参考方案10】:在 Python 3 中,有正当理由使用 print over sys.stdout.write
,但这个理由也可以变成使用 sys.stdout.write
的理由。
这个原因是,现在 print 是 Python 3 中的一个函数,你可以覆盖它。因此,您可以在一个简单的脚本中随处使用 print,并决定那些打印语句需要写入 stderr
。您现在可以重新定义打印功能,您甚至可以通过使用内置模块更改打印功能来全局更改它。当然,使用file.write
,您可以指定文件是什么,但通过覆盖打印,您还可以重新定义行分隔符或参数分隔符。
反之亦然。也许您绝对确定您写信给stdout
,但也知道您要将打印更改为其他内容,您可以决定使用sys.stdout.write
,并将打印用于错误日志或其他内容。
因此,您使用什么取决于您打算如何使用它。 print
更灵活,但这可能是使用和不使用它的原因。我仍然会选择灵活性,并选择打印。使用print
的另一个原因是熟悉度。现在有更多人会知道您所说的印刷品是什么意思,而更少人知道sys.stdout.write
。
【讨论】:
【参考方案11】:最好在动态打印有用的情况下,例如在较长的过程中提供信息:
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)
【讨论】:
print(time_msg, end='') 代替 sys.stdout.write(time_msg) sys.stdout.flush() 也有效【参考方案12】:>>> 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
观察上面的例子:
sys.stdout.write
不会写入非字符串对象,但print
会
sys.stdout.write
不会在末尾添加换行符,但print
会
如果我们深入潜水,
sys.stdout
是一个文件对象,可用于 print() 的输出
如果print()
的文件参数未指定,则使用sys.stdout
【讨论】:
【参考方案13】:在尝试将字节打印为其十六进制外观时,其中一个区别如下。例如,我们知道255
的十进制值是十六进制的0xFF
:
val = ':02x'.format(255)
sys.stdout.write(val) # Prints ff2
print(val) # Prints ff
【讨论】:
这不是这个问题。它只会发生在交互式 shell 中,因为...write()
没有添加 \n
并返回(和交互式 shell 显示)函数的返回值(写入的字符数)、十六进制表示或任何其他正在显示的内容是无关紧要的.【参考方案14】:
在 Python 2 中,如果需要传递函数,则可以将 os.sys.stdout.write
分配给变量。您不能使用 print
执行此操作(在 REPL 中)。
>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>>
按预期工作。
>>> cmd=print
File "<stdin>", line 1
cmd=print
^
SyntaxError: invalid syntax
那行不通。 print
是一个神奇的功能。
【讨论】:
【参考方案15】:print
和 sys.stdout.write
在 Python 3 中的区别也是在终端中执行时返回的值。在 Python 3 中,sys.stdout.write
返回字符串的长度,而 print
只返回 None
。
因此,例如在终端中以交互方式运行以下代码将打印出字符串及其长度,因为在交互运行时会返回并输出长度:
>>> sys.stdout.write(" hi ")
hi 4
【讨论】:
以上是关于sys.stdout.write 和 print 的区别?的主要内容,如果未能解决你的问题,请参考以下文章
python中print(obj) 与sys.stdout.write()的区别
[Python]sys.stdin.readline(), sys.stdout.write(), sys.stdin.write()