Python:contextlib.redirect_stdout有时并不能实时工作

时间:2017-09-12 08:12:10

标签: python io-redirection buffering

我在Ubuntu上使用Python3.5。以下脚本创建了一个文件<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script type="text/javascript"> function check() { $(".someClass").prop("disabled", false); } </script> <form> <select class="someClass" name="someName" id="enabledDropDown" onchange="check()"> <option>Data1</option> <option>Data2</option> </select> <br> <select class="someClass" name="someName" multiple id="someId" disabled> <option>Data3</option> <option>Data4</option> <option>Data5</option> <option>Data6</option> <option>Data7</option> <option>Data8</option> </select> <br> <select class="someClass" name="someName" multiple id="someId2" disabled> <option>Data9</option> <option>Data10</option> <option>Data11</option> <option>Data12</option> <option>Data13</option> <option>Data14</option> </select> </form> ,并使用越来越多的&#34; Hello&#34;:

来填充它
out

但是,如果我通过添加对import contextlib with contextlib.redirect_stdout(open('out','w')): while True: print('Hello') 的调用进行微小修改,则文件time.sleep()将保持为空:

out

如果我通过将循环转换为有限循环来进一步更改代码,它将填充import contextlib import time with contextlib.redirect_stdout(open('out','w')): while True: print('Hello') time.sleep(1) ,但仅在循环结束时填充。

任何人都可以复制并解释它吗?

2 个答案:

答案 0 :(得分:2)

这是由输出缓冲引起的。考虑到contextlib的使用,这是一个有趣的案例,但基本问题在于open('out', 'w')语句。

要防止输出缓冲,如果您使用的是Python 2,则可以将buffering argument设置为0

import contextlib
import time

with contextlib.redirect_stdout(open('out','w', 0)):
    while True:
        print 'Hello'
        time.sleep(1)

或者,一旦上下文管理器关闭文件(或缓冲内容超过一定大小),就会写入文件内容。

如果您正在使用Python 3,那么您将无法获得无缓冲的文本I / O(请在评论中指出)。但是,在每个循环结束时刷新stdout应该具有所需的效果:

import contextlib
import time
import sys

with contextlib.redirect_stdout(open('out','w')):
    while True:
        print('Hello')
        sys.stdout.flush()
        time.sleep(1)

答案 1 :(得分:1)

我打赌以前曾经问过,但我找不到好的副本。

这是由输出缓冲引起的。当stdout进入终端时,它是行缓冲的,这意味着每次遇到"\n"时,输出都会从程序发送到终端。但是当stdout引用文件时,它是块缓冲的。这意味着仅当缓冲区变满时(或者当您明确刷新它或句柄关闭时)才会生成实际输出。