sys.stdout.write和print的区别?

是否存在sys.stdout.write()优于print的情况?

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

735247 次浏览

在Python 2中。x, print语句预处理你给它的东西,把它转换成字符串,处理分隔符和换行符,并允许重定向到文件。Python 3。X将其转换为一个函数,但它仍然具有相同的职责。

sys.stdout是一个文件或类文件类,它有一些方法用于写入它,这些方法接受字符串或这一行的东西。

print首先将对象转换为字符串(如果它还不是字符串)。如果对象不是行首,它也会在对象前加一个空格,在对象末尾加一个换行符。

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

所以

print 99

等价于:

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

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成为一个函数,但由于__abc2参数,它仍然可以传递除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
我的问题是是否有 在这些情况下 sys.stdout.write()更可取 print < / p >

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

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

下面是一些基于Mark Lutz的书学习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

我的问题是,在某些情况下,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:模式,但有时它是值得的。

至少在一种情况下,你需要sys.stdout而不是print。

当你想覆盖一行而不去到下一行时,例如在绘制进度条或状态消息时,你需要遍历类似于

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

由于print添加了换行符,所以最好使用sys.stdout

是否存在sys.stdout.write()优于 打印吗?< / p >

例如,我正在编写一个小函数,该函数在传递数字作为参数时以金字塔格式打印星星,尽管您可以使用< em >结束= " " < / em >在单独的行中打印来完成此任务,但我使用< em > sys.stdout.write < / em >< em > < / em >打印配合使用来实现此工作。要详细说明这一点,stdout.write打印在同一行中,而打印总是在单独的行中打印其内容。

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)

是否存在sys.stdout.write()比print更可取的情况?

我发现在多线程情况下,stdout比print工作得更好。我使用队列(先进先出)来存储要打印的行,并且在打印行之前保留所有线程,直到打印队列为空。即便如此,使用print有时会在调试I/O上丢失最后的\n(使用Wing Pro IDE)。

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

在Python 3中,使用sys.stdout.write打印是有正当理由的,但这个理由也可以变成使用sys.stdout.write的理由。

这个原因是,现在print是python3中的一个函数,你可以重写它。因此,你可以在一个简单的脚本中到处使用print,并决定这些print语句需要改为写入stderr。你现在可以重新定义打印函数,你甚至可以通过使用内置模块改变打印函数全局。当然,使用file.write,你可以指定文件是什么,但通过覆盖打印,你也可以重新定义行分隔符或参数分隔符。

反之亦然。也许你绝对确定要写入stdout,但也知道要将print更改为其他内容,你可以决定使用sys.stdout.write,并将print用于错误日志或其他内容。

所以,你使用什么取决于你打算如何使用它。print更灵活,但这可能是使用和不使用它的原因。我还是会选择比较灵活的款式,选择印花。另一个使用print的原因是熟悉度。现在越来越多的人知道你说的印刷是什么意思,而更少的人知道sys.stdout.write

当动态打印有用时,例如,在一个较长的过程中提供信息:

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)
>>> 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

其中一个区别如下,当试图将一个字节打印为其十六进制外观时。例如,我们知道255的十进制值是十六进制形式的0xFF:

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


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

在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是一个神奇的函数。

Python 3中指出的printsys.stdout.write之间的区别还在于在终端中执行时返回的值。在Python 3中,sys.stdout.write返回字符串的长度,而print只返回None

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

>>> sys.stdout.write(" hi ")
hi 4

你问,

sys.stdout.writeprint之间的区别是什么?`

我所知道的解释它的最好方法是告诉你如何用sys.stdout来写print

下面我提供了三种不同的方法来实现python的print函数:

实现1

import sys


def print(*args, sep=" ", file=sys.stdout, end="\n") -> None:
# implementation One
file.write(sep.join(str(arg) for arg in args))
file.write(end)

实现2

def print(*args, sep=" ", file=sys.stdout, end="\n") -> None:
# Implementation 2
file.write(str(args[0]))
for arg in args[1:]:
file.write(sep)
file.write(str(arg))
file.write(end)
return

实现3

def print(*args, sep=" ", file=sys.stdout, end="\n") -> None:
# implementation 3
it = iter(args)
arg = next(it)
file.write(str(arg))
try:
while True:
arg = next(it)
file.write(sep)
file.write(str(arg))
except StopIteration:
pass
file.write(end)
return None