如何刷新打印功能的输出?

Wal*_*sen 1111 python printing flush python-3.x

如何强制Python的打印功能输出到屏幕?

这不是禁用输出缓冲的重复- 链接的问题是尝试无缓冲输出,而这是更一般的.这个问题的最佳答案太强大或涉及到这个问题(他们不是很好的答案),这个问题可以在谷歌上找到一个相对新手.

Ces*_*arB 1297

print("Hello world!", flush=True)
Run Code Online (Sandbox Code Playgroud)

默认打印打印到print.

参考文献:

  • 可能很晚了,但如果你希望你的打印始终像@Charlie Parker一样刷新,你可以使用 `print = functools.partial(print,lush=True)` (24认同)
  • `python -u <script.py>` 为我工作,无需修改脚本。 (6认同)
  • 不,每次调用“print”时,您都需要执行“sys.stdout.flush()”(或在 Python 3 中使用“print(...,flush=True)”)。检查[此答案](/sf/answers/16154631/)是否有其他可能适合您的解决方案。 (4认同)
  • 如果我执行`sys.stdout.flush()`我可以避免输入flush关键字吗?我的文件中有很多打印内容,并且不想更改它们+我希望我的文件始终刷新,并且我不想永远写入它。我想要的就是永远冲洗。将“sys.stdout.flush()”放在顶部就足够了吗?(我使用的是python 3及以上版本) (3认同)

gim*_*mel 334

运行python -h,我看到一个命令行选项:

-u:无缓冲的二进制stdout和stderr; 还有PYTHONUNBUFFERED = x有关'-u'的内部缓冲的详细信息,请参阅手册页

这是相关的文档.

  • 如果您在 Linux/Unix 平台上运行它,您可以在解释器命令行(脚本文件的第一行)中添加 `-u`,因此将第一行从(类似)`#!/usr/ 更改为bin/python3` 到 `#!/usr/bin/python3 -u` - 现在,当您运行脚本(例如 `./my_script.py`)时,将始终为您添加 `-u` (3认同)

Eug*_*ine 318

从Python 3.3开始,您可以强制执行正常print()功能而无需使用sys.stdout.flush(); 只需将"flush"关键字参数设置为true即可.从文档:

print(*objects,sep ='',end ='\n',file = sys.stdout,flush = False)

将对象打印到流文件,由sep分隔,然后结束.sep,end和file(如果存在)必须作为关键字参数给出.

所有非关键字参数都转换为字符串,如str(),并写入流,由sep分隔,后跟end.sep和end都必须是字符串; 它们也可以是None,这意味着使用默认值.如果没有给出对象,print()将只写入结束.

file参数必须是带有write(string)方法的对象; 如果它不存在或None,将使用sys.stdout.输出是否缓冲通常由文件确定,但如果flush关键字参数为true,则强制刷新流.


Aar*_*all 171

如何刷新Python打印输出?

我建议五种方法:

  • 在Python 3中,调用print(..., flush=True)(在Python 2的print函数中不提供flush参数,并且print语句没有模拟).
  • 调用file.flush()输出文件(我们可以包装python 2的print函数来执行此操作),例如,sys.stdout
  • 将此
    print = partial(print, flush=True)应用于具有部分功能的模块中的每个打印函数调用,应用于模块全局.
  • 使用-u传递给interpreter命令的flag()将此应用于进程
  • 将此应用于环境中的每个python进程PYTHONUNBUFFERED=TRUE(并取消设置该变量以撤消此操作).

Python 3.3+

使用Python 3.3或更高版本,您只需提供函数flush=True的关键字参数print:

print('foo', flush=True) 
Run Code Online (Sandbox Code Playgroud)

Python 2(或<3.3)

他们没有flush向Python 2.7 反向移植参数.因此,如果您使用的是Python 2(或者小于3.3),并且希望代码兼容2和3,我可以建议使用以下兼容性代码.(注意__future__导入必须位于/非常"接近模块顶部 "):

from __future__ import print_function
import sys

if sys.version_info[:2] < (3, 3):
    old_print = print
    def print(*args, **kwargs):
        flush = kwargs.pop('flush', False)
        old_print(*args, **kwargs)
        if flush:
            file = kwargs.get('file', sys.stdout)
            # Why might file=None? IDK, but it works for print(i, file=None)
            file.flush() if file is not None else sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

上述兼容性代码将涵盖大多数用途,但对于更彻底的处理,请参阅该six模块.

或者,您可以file.flush()在打印后调用,例如,使用Python 2中的print语句:

import sys
print 'delayed output'
sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

将一个模块中的默认值更改为 flush=True

您可以在模块的全局范围内使用functools.partial更改print函数的默认值:

import functools
print = functools.partial(print, flush=True)
Run Code Online (Sandbox Code Playgroud)

如果你看看我们的新的部分函数,​​至少在Python 3中:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
Run Code Online (Sandbox Code Playgroud)

我们可以看到它像正常一样工作:

>>> print('foo')
foo
Run Code Online (Sandbox Code Playgroud)

我们实际上可以覆盖新的默认值:

>>> print('foo', flush=False)
foo
Run Code Online (Sandbox Code Playgroud)

再次注意,这只会更改当前的全局范围,因为当前全局范围上的打印名称将使内置print函数蒙上阴影(或者在当前全局范围内取消引用兼容性函数,如果使用Python 2).

如果要在函数内而不是在模块的全局范围内执行此操作,则应为其指定不同的名称,例如:

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')
Run Code Online (Sandbox Code Playgroud)

如果在函数中声明它是全局函数,那么您将在模块的全局命名空间中更改它,因此您应该将它放在全局命名空间中,除非该特定行为正是您想要的.

更改进程的默认值

我认为这里最好的选择是使用该-u标志来获得无缓冲的输出.

$ python -u script.py
Run Code Online (Sandbox Code Playgroud)

要么

$ python -um package.module
Run Code Online (Sandbox Code Playgroud)

来自文档:

强制stdin,stdout和stderr完全无缓冲.在重要的系统上,还将stdin,stdout和stderr置于二进制模式.

请注意,file.readlines()和File Objects(对于sys.stdin中的行)中存在内部缓冲,不受此选项的影响.要解决此问题,您需要在while 1:循环中使用file.readline().

更改shell操作环境的默认值

如果将环境变量设置为非空字符串,则可以对环境中继承的环境中的所有python进程获取此行为:

例如,在Linux或OSX中:

$ export PYTHONUNBUFFERED=TRUE
Run Code Online (Sandbox Code Playgroud)

或Windows:

C:\SET PYTHONUNBUFFERED=TRUE
Run Code Online (Sandbox Code Playgroud)

来自文档:

PYTHONUNBUFFERED

如果将其设置为非空字符串,则等同于指定-u选项.


附录

这是Python 2.7.12中打印函数的帮助 - 请注意,没有 flush参数:

>>> from __future__ import print_function
>>> help(print)
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout)

    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file: a file-like object (stream); defaults to the current sys.stdout.
    sep:  string inserted between values, default a space.
    end:  string appended after the last value, default a newline.
Run Code Online (Sandbox Code Playgroud)

  • 对于从较低 Python 版本的好奇迁移:`__future__` 版本不包含 `flush` 因为“flush 参数是在 Python 3.3 中添加的(在 print() 通过 future 导入向后移植到 2.7 之后)” https:// bugs.python.org/issue28458 (2认同)

Ant*_*ins 69

同样如本博客所示,可以sys.stdout在无缓冲模式下重新打开:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
Run Code Online (Sandbox Code Playgroud)

每个stdout.writeprint操作后自动刷新.

  • 糟糕,Python 3发现了。它不会让我执行这段代码! (3认同)
  • 在python 2.7中的Ubuntu 12.04上,这给了我'UnsupportedOperation:IOStream没有fileno. (2认同)

Noa*_*ser 61

使用Python 3.x,该print()功能已得到扩展:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Run Code Online (Sandbox Code Playgroud)

所以,你可以这样做:

print("Visiting toilet", flush=True)
Run Code Online (Sandbox Code Playgroud)

Python文档录入

  • 它与 [Eugene Sajine 的答案](/sf/ask/16152601/#23142556) 有什么不同? (2认同)

Dan*_*ski 36

使用-u命令行开关工作,但它有点笨拙.这意味着如果用户在没有-u选项的情况下调用脚本,程序可能会出现错误行为.我通常使用自定义stdout,如下所示:

class flushfile:
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)
Run Code Online (Sandbox Code Playgroud)

...现在所有的print电话(sys.stdout隐式使用)将自动flush编辑.

  • 我建议不要继承文件,然后通过添加委托给stdout.`def __getattr __(self,name):return object .__ getattribute __(self.f,name)` (4认同)
  • 如果没有@diedthreetimes评论建议的更改,我会得到"ValueError:关闭文件的I/O操作" (2认同)

小智 19

为什么不尝试使用无缓冲的文件?

f = open('xyz.log', 'a', 0)
Run Code Online (Sandbox Code Playgroud)

要么

sys.stdout = open('out.log', 'a', 0)
Run Code Online (Sandbox Code Playgroud)

  • 他不想创建一个无缓冲的文件;他想让现有的标准输出(重定向到控制台、终端或其他任何东西:这不能改变)无缓冲。 (2认同)

Kam*_*iel 13

丹的想法不太奏效:

#!/usr/bin/env python
class flushfile(file):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

print "foo"
Run Code Online (Sandbox Code Playgroud)

结果:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file
Run Code Online (Sandbox Code Playgroud)

我相信问题是它继承自文件类,实际上并不是必需的.根据sys.stdout的文档:

stdout和stderr不需要是内置文件对象:任何对象都是可接受的,只要它有一个带有字符串参数的write()方法即可.

如此改变

class flushfile(file):
Run Code Online (Sandbox Code Playgroud)

class flushfile(object):
Run Code Online (Sandbox Code Playgroud)

让它工作得很好.

  • 没有投票,因为这是IS @ Dan的解决方案...(你应该评论Dan的帖子,而不是复制他的解决方案) (16认同)

gue*_*tli 8

这是我的版本,它也提供了writelines()和fileno():

class FlushFile(object):
    def __init__(self, fd):
        self.fd = fd

    def write(self, x):
        ret = self.fd.write(x)
        self.fd.flush()
        return ret

    def writelines(self, lines):
        ret = self.writelines(lines)
        self.fd.flush()
        return ret

    def flush(self):
        return self.fd.flush

    def close(self):
        return self.fd.close()

    def fileno(self):
        return self.fd.fileno()
Run Code Online (Sandbox Code Playgroud)


小智 6

在Python 3中,您可以覆盖打印功能,默认设置为 flush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)
Run Code Online (Sandbox Code Playgroud)

  • 考虑到所有其他高质量的回答,这个答案似乎有点不足。您可能需要添加更多内容。 (2认同)

kma*_*o23 5

我在Python 3.4中这样做:

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')
Run Code Online (Sandbox Code Playgroud)


Gui*_*eot 5

我首先很难理解冲洗选项是如何工作的。我想做一个“加载显示”,这是我找到的解决方案:

for i in range(100000):
    print('{:s}\r'.format(''), end='', flush=True)
    print('Loading index: {:d}/100000'.format(i+1), end='')
Run Code Online (Sandbox Code Playgroud)

第一行刷新先前的打印,第二行打印新的更新消息。我不知道这里是否存在单行语法。


归档时间:

查看次数:

717680 次

最近记录:

6 年 前