python contextmanager换行问题

发布于 2021-01-29 15:05:52

我想使用Python的contextmanager生成一个包装器,以显示特定代码块的类似Linux的进度:

Doing something... done. [42 ms]

这是可行的-一种:

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))

此用法示例应打印 “正在做某事…” 而没有换行符,请稍等片刻,打印 “完成。[1000 ms]”, 包括换行符并退出。

with msg("Doing something"):
    time.sleep(1)

但是,在运行代码段时,输出 首先 等待一秒钟, 然后
输出整行。end=''在第一个print()语句中删除所有内容时,都可以按预期方式工作,但是要付出难看的输出。

为什么会这样,这是故意的,可以采取什么措施避免这种行为?

(Linux Mint 17.1上的Python 3.4.0)

关注者
0
被浏览
54
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    问题可能是由于缓冲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之前,您必须使用以下flush方法stdout

    print(m + "... ", end='')
    sys.stdout.flush()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看