почему консоль python работает иначе, чем простоя

Может ли кто-нибудь сказать мне, почему этот код работает в консоли Python иначе, чем в IDLE?

print('Do not press enter before the program says go.\n', end = '')
try:
    while True:
        input('Ready?')
        print('Starting', end = '')
        for i in range(secrets.randbits(3)):
            time.sleep(1)
            print(' .', end = '')
        now = datetime.datetime.now()
        input('\nGo!')
        print('\nReaction: {}'.format(datetime.datetime.now()-now))
except KeyboardInterrupt:
    print('Exiting.')

Это вывод в IDLE, который работает так, как я ожидаю:

Do not press enter before the program says go.
Ready?
Starting . .
Go!

Reaction: 0:00:00.328174

Но когда в консоли я получаю тот же общий вывод, но точки не появляются одна за другой, вместо этого они появляются все сразу с помощью go. Может ли кто-нибудь объяснить это странное поведение. Я использую Python 3.6.2, если это поможет.

У меня есть способ проверить, работает ли программа из IDLE или нет, которая возвращает true, если в режиме ожидания, и false, если не в режиме ожидания:

def inIDLE():
    import sys
    if 'idlelib.run' in sys.modules:
        return True
    else:
        return False

person Lasagnenator    schedule 30.09.2017    source источник
comment
У IDLE есть несколько особенностей; обычная консоль ведет себя правильно. Если вы не хотите, чтобы ваши точки появлялись все сразу, вы можете указать консоли сбросить вывод: print(' .', end = '', flush=True)   -  person PM 2Ring    schedule 30.09.2017
comment
Ах, вот это решение, которое я искал. Я понятия не имел, как использовать флеш, но теперь знаю. Спасибо за помощь @PM2Ring   -  person Lasagnenator    schedule 30.09.2017


Ответы (1)


Поскольку это программа с графическим интерфейсом (работает на Tkinter), IDLE имеет несколько особенностей; обычная консоль на самом деле ведет себя правильно, поскольку вывод на stdout обычно буферизуется строкой.

Если вы не хотите, чтобы ваши точки появлялись все сразу, вы можете указать консоли сбросить вывод:

print(' .', end = '', flush=True)

В качестве альтернативы вы можете печатать в stderr, который обычно не буферизуется:

import sys
#...
print(' .', end = '', file=sys.stderr)

В консоли вы можете выбрать небуферизованный stdout, передав опцию -u интерпретатору, подробности см. в python3 -h.

person PM 2Ring    schedule 30.09.2017