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

Python 如何刷新打印功能的输出?,python,python-3.x,printing,flush,Python,Python 3.x,Printing,Flush,如何强制Python的print函数输出到屏幕?在Python 3中,可以使用可选的flush参数: print("Hello, World!", flush=True) >>> from __future__ import print_function >>> help(print) print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout)

如何强制Python的
print
函数输出到屏幕?

在Python 3中,可以使用可选的
flush
参数:

print("Hello, World!", flush=True)
>>> 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.
在Python2中,您必须

import sys
sys.stdout.flush()

调用
后打印
。默认情况下,打印到(有关详细信息,请参阅文档)。

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

-u:无缓冲二进制标准输出和标准输出;另外,PYTHONUNBUFFERED=x 有关'-u'的内部缓冲的详细信息,请参见手册页


下面是使用
-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)
。。。现在,您所有的
print
调用(隐式使用
sys.stdout
)都将自动
flush
ed。

无法正常工作:

#!/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"
结果是:

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


使其工作正常。

使用无缓冲文件:

f = open('xyz.log', 'a', 0)


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

此外,如中所述,可以在无缓冲模式下重新打开系统标准输出:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

每个
stdout.write
print
操作之后都将自动刷新。

自Python 3.3以来,您可以强制正常的
print()
函数刷新,而无需使用
sys.stdout.flush()
;只需将“flush”关键字参数设置为true。发件人:

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

将对象打印到流文件中,以sep分隔,后跟end。sep、end和file(如果存在)必须作为关键字参数提供

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

文件参数必须是具有写入(字符串)方法的对象;如果不存在或没有,将使用sys.stdout输出是否缓冲通常由文件决定,但如果flush关键字参数为true,则强制刷新流。


我在Python 3.4中是这样做的:

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

在Python 3.x中,
print()
函数已被扩展:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
所以,你可以这样做:

print("Visiting toilet", flush=True)

如何刷新Python打印的输出? 我建议五种方法:

  • 在Python3中,调用
    print(…,flush=True)
    (在Python2的print函数中flush参数不可用,并且print语句没有类似的参数)
  • 在输出文件上调用
    file.flush()
    (我们可以包装Python2的打印函数来完成此操作),例如,
    sys.stdout
  • 将此应用于模块中具有部分函数的每个打印函数调用,
    print=partial(print,flush=True)
    应用于全局模块
  • 将此应用于传递给解释器命令的标志(
    -u
    )的进程
  • 使用
    PYTHONUNBUFFERED=TRUE
    将此应用于环境中的每个python进程(并取消设置变量以撤消此操作)
Python 3.3+ 使用Python 3.3或更高版本,您只需将
flush=True
作为关键字参数提供给
print
函数:

print('foo', flush=True) 
Python 2(或<3.3) 他们没有将
flush
参数向后移植到Python2.7,因此,如果您使用的是Python2(或小于3.3),并且希望代码与2和3兼容,我建议您使用以下兼容代码。(请注意,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
导入必须位于/非常“接近”):

将一个模块中的默认值更改为
flush=True
您可以在模块的全局范围内使用functools.partial更改打印函数的默认值:

import functools
print = functools.partial(print, flush=True)
如果您看看我们的新分部函数,至少在Python 3中是这样:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
我们实际上可以覆盖新的默认值:

>>> print('foo', flush=False)
foo
请再次注意,这只会更改当前全局作用域,因为当前全局作用域上的打印名称将覆盖内置的
print
函数(或者如果在Python 2中使用兼容函数,则在当前全局作用域中取消对兼容函数的引用)

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

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')
如果在函数中声明它是全局的,那么就是在模块的全局名称空间中更改它,所以应该将它放在全局名称空间中,除非该特定行为正是您想要的

更改进程的默认值 我认为这里最好的选择是使用
-u
标志来获得无缓冲输出

$ python -u script.py

从:

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

请注意,file.readlines()和文件对象(用于sys.stdin中的行)中有内部缓冲,不受此选项的影响。要解决这个问题,您需要在while 1:loop中使用file.readline()

更改shell操作环境的默认值 如果将环境变量设置为非空字符串,则可以为环境中的所有python进程或从环境继承的环境获取此行为:

e、 例如,在Linux或OSX中:

$ export PYTHONUNBUFFERED=TRUE
或窗口:

C:\SET PYTHONUNBUFFERED=TRUE
从:

未缓冲的python

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


补遗 下面是Python 2.7.12中关于打印函数的帮助-请注意,没有
flush
参数:

print("Hello, World!", flush=True)
>>> 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.

在Python3中,您可以将打印函数的默认值设置为
flush=True

<
def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')
$ python -u script.py
$ python -um package.module
$ export PYTHONUNBUFFERED=TRUE
C:\SET PYTHONUNBUFFERED=TRUE
>>> 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.
for i in range(100000):
    print('{:s}\r'.format(''), end='', flush=True)
    print('Loading index: {:d}/100000'.format(i+1), end='')