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() 最好 print

前几天完成脚本开发后,我将它上传到了一个unix服务器。我所有的调试消息都使用了print 语句,并且这些不会出现在服务器日志中。

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

【讨论】:

嗯?您确定这是print()sys.stdout.write() 之间的区别,而不是stdoutstderr 之间的区别吗?对于调试,您应该使用logging 模块,它将消息打印到stderr 是的。使用nohup 并重定向到.out 文件也是如此。 使用 sys.stdout.flush() 会有所帮助。 如果你使用nohup,默认情况下所有写到stdoutstderr的都会重定向到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()print 更可取

如果您正在编写一个可以写入文件和标准输出的命令行应用程序,那么它很方便。您可以执行以下操作:

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.writeprint 配合来完成此操作工作。详细说明此 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】:

printsys.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()

Python 标准输出 sys.stdout 重定向

进度条

Python中print和input调用了Python中底层的什么方法

python中sys.stdoutsys.stdin