python contextmanager换行问题 [英] python contextmanager newline issue
问题描述
使用 Python 的 contextmanager 我想生成一个包装器显示某个代码块的类似 Linux 的进度:
Using Python's contextmanager I want to generate a wrapper to display Linux-like progress of a certain block of code:
做某事...完成.[42 毫秒]
这是有效的 - 有点:
This is working - kind of:
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]" 包括一个换行并退出.
This usage example should print "Doing something... " without a line break, wait for a second, print "done. [1000 ms]" including a line break and quit.
with msg("Doing something"):
time.sleep(1)
但是,当运行代码段时,输出 first 等待一秒钟,然后 after 打印整行.在第一个 print()
语句中删除 end=''
时,一切都按预期工作,但代价是输出丑陋.
However, when running the snippet, the output first waits for a second, and afterwards prints the whole line. When removing end=''
at the first print()
statement everything works as expected, but at the cost of an ugly output.
为什么会出现这种情况,这是有意为之,可以采取哪些措施来避免这种行为?
Why is this the case, is this intended, and what could be done to avoid this behavior?
(Linux Mint 17.1 上的 Python 3.4.0)
推荐答案
该问题可能是由于 stdout
的缓冲造成的.您需要手动刷新它才能显示消息.在 Python 3.3+ 中,print
函数有一个 flush
参数:
The problem is probably due to buffering of stdout
. You need to manually flush it for the message to be displayed. In Python 3.3+, the print
function has a flush
argument:
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
方法:
Prior to 3.3, you would have to use the flush
method of stdout
:
print(m + "... ", end='')
sys.stdout.flush()
这篇关于python contextmanager换行问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!