Python print函数输出刷新方法

Python print函数输出刷新方法

技术背景

在Python中,print函数的输出有时会被缓冲,这可能导致在某些情况下,输出不会立即显示在终端上。例如,在需要实时显示进度信息的程序中,就需要手动刷新输出,以确保信息能及时显示。

实现步骤

Python 3.3+

在Python 3.3及以上版本,可以直接在print函数中使用flush=True参数:

1
print('foo', flush=True)

Python 2(或 < 3.3)

由于Python 2的print函数没有flush参数,若要实现兼容Python 2和3的代码,可以使用以下方式:

1
2
3
4
5
6
7
8
9
10
11
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)
file.flush() if file is not None else sys.stdout.flush()

全局设置刷新

可以使用partial函数将flush=True应用到模块全局的print函数:

1
2
from functools import partial
print = partial(print, flush=True)

使用命令行标志

在运行Python脚本时,可以使用-u标志来实现无缓冲输出:

1
python -u script.py

设置环境变量

在Linux或OSX系统中:

1
export PYTHONUNBUFFERED=TRUE

在Windows系统中:

1
SET PYTHONUNBUFFERED=TRUE

核心代码

Python 3.3+直接刷新

1
print('实时输出信息', flush=True)

Python 2兼容代码

1
2
3
4
5
6
7
8
9
10
11
12
13
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)
file.flush() if file is not None else sys.stdout.flush()

print('兼容Python 2和3的输出', flush=True)

自定义FlushFile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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.fd.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()

import sys
sys.stdout = FlushFile(sys.stdout)
print('使用自定义类刷新输出')

最佳实践

实时进度显示

1
2
for i in range(100):
print(f'\r当前进度: {i}%', end='', flush=True)

重写print函数

1
2
3
4
def print(*args, **kwargs):
__builtins__.print(*args, flush=True, **kwargs)

print('所有输出自动刷新')

常见问题

flushfile类继承file类报错

在Python 2中,若flushfile类继承file类,会出现ValueError: I/O operation on closed file错误。解决方法是将其继承object类:

1
2
3
4
5
6
7
8
9
10
11
class flushfile(object):
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('修改后正常输出')

-u标志可能导致行为不一致

使用-u命令行标志时,如果用户在调用脚本时未使用该选项,程序可能会出现异常。可以使用自定义stdout的方式来避免这个问题。


Python print函数输出刷新方法
https://119291.xyz/posts/python-print-output-flush-methods/
作者
ww
发布于
2025年5月29日
许可协议