使用 Python 的 contextmanager我想生成一个包装器来显示某个代码块的类似 Linux 的进度:
做某事...完成。 [42 毫秒]
这是有效的 - 有点:
from contextlib import contextmanager
import time
@contextmanager
def msg(m):
print(m + "... ", end='')
t_start = time.time()
yield
t_duration_ms = 1000 * (time.time() - t_start)
print("done. [{:.0f} ms]".format(t_duration_ms))
这个用法示例应该打印“Doing something...” 没有换行符,等一下,打印“done.[1000 ms]”包括一个换行并退出。
with msg("Doing something"):
time.sleep(1)
但是,在运行代码段时,输出first 等待一秒钟,然后afterwards 打印整行。在第一个 print()
语句中删除 end=''
时,一切都按预期工作,但代价是输出丑陋。
为什么会这样,是否有意为之,如何避免这种行为?
(Linux Mint 17.1 上的 Python 3.4.0)
最佳答案
问题可能是由于 stdout
的缓冲造成的。您需要手动刷新它才能显示消息。在 Python 3.3+ 中,print
函数有一个 flush
参数:
from contextlib import contextmanager
import time
@contextmanager
def msg(m):
print(m + "... ", end='', flush=True)
t_start = time.time()
yield
t_duration_ms = 1000 * (time.time() - t_start)
print("done. [{:.0f} ms]".format(t_duration_ms))
在 3.3 之前,您必须使用 stdout
的 flush
方法:
print(m + "... ", end='')
sys.stdout.flush()
关于python 上下文管理器换行问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30828495/