В этом коде есть несколько отдельных проблем:
while run:
# loop through each line of user input, adding it to buffer
for line in sys.stdin.readlines():
if line == 'quit':
run = False
Во-первых, у вас есть внутренний цикл, который не завершится, пока не будут обработаны все строки, даже если вы в какой-то момент наберете quit. Настройка run = False
не выходит из этого цикла. Вместо выхода, как только вы наберете quit, он будет продолжать работу до тех пор, пока не просмотрит все строки, и затем завершит работу, если вы набрали quit в любой момент.
Вы можете легко это исправить, добавив break
после run = False
.
Но, с этим исправлением или без него, если вы не набрали quit в первый раз во внешнем цикле, поскольку вы уже прочитали все введенные данные, читать больше нечего, поэтому вы просто продолжайте запускать пустой внутренний цикл снова и снова, из которого вы никогда не сможете выйти.
У вас есть цикл, который означает чтение и обработку всего ввода. Вы хотите сделать это ровно один раз. Итак, каким должен быть внешний цикл? Во всяком случае, этого не должно быть; способ сделать что-то один раз — не использовать цикл. Итак, чтобы исправить это, избавьтесь от run
и цикла while run:
; просто используйте внутренний цикл.
Затем, если вы наберете quit, line
на самом деле будет "quit\n"
, потому что readlines
не удаляет символы новой строки.
Вы исправите это, либо проверив "quit\n"
, либо strip
проверив линии.
Наконец, даже если вы устраните все эти проблемы, вам все равно придется вечно ждать, прежде чем что-либо предпринять. readlines
возвращает list
строк. Единственный способ сделать это — прочитать все строки, которые когда-либо будут в stdin
. Вы даже не сможете начать цикл, пока не прочтете все эти строки.
Когда стандартный ввод является файлом, это происходит, когда файл заканчивается, так что это не слишком ужасно. Но когда стандартным вводом является командная строка Windows, командная строка никогда не заканчивается.* Так что это длится вечно. Вы не можете начать обработку списка строк, потому что ожидание списка строк занимает целую вечность.
Решение состоит в том, чтобы не использовать readlines()
. На самом деле никогда не бывает веских причин вызывать readlines()
для чего бы то ни было, stdin
или нет. Все, над чем работает readlines
, является уже итерируемым, заполненным строками, точно так же, как list
, который дал бы вам readlines
, за исключением того, что он ленив: он может давать вам строки по одной, вместо того, чтобы ждать и давая вам все сразу. (И даже если вам действительно нужен список, просто введите list(f)
вместо f.readlines()
.)
Итак, вместо for line in sys.stdin.readlines():
просто выполните for line in sys.stdin:
(или, лучше, полностью замените явный цикл и используйте последовательность преобразований итератора, как в ответе мгилсона.)
Все исправления, предложенные JBernardo, Wing Tang Wong и т. д., правильны и необходимы. Причина, по которой ни один из них не исправил ваши проблемы, заключается в том, что если у вас есть 4 ошибки и вы исправите 1, ваш код все равно не работает. Именно поэтому не работает не является полезной мерой чего-либо в программировании, и вы должны отлаживать то, что на самом деле идет не так, чтобы знать, делаете ли вы успехи.
* Я немного солгал о том, что stdin
никогда не будет закончен. Если вы наберете контроль-Z (вам может понадобиться или не понадобиться следовать за ним с возвратом), то stdin
завершается. Но если ваше задание состоит в том, чтобы заставить его выйти, как только пользователь введет quit‹, превратив что-то, что завершается только тогда, когда пользователь вводит quit, а затем возвращает, control-Z, return снова, вероятно, не будет считаться успешным.
person
abarnert
schedule
28.03.2013
'quit' != 'quit\n'
- person JBernardo   schedule 29.03.2013line
будет иметь'\n'
в конце, так что вы никогда не столкнетесь с условиемrun = False
. - person mgilson   schedule 29.03.2013sys.stdin.readlines()
. Это возвращаетlist
строк. Очевидно, что он не может сделать этоlist
, пока не соберет все строки, что означает, что он не может вернуться, пока вы не закроете стандартный ввод. Решение этой проблемы состоит в том, чтобы просто… не звонитьreadlines()
. Вполне возможно, что у вас возникла новая проблема после решения этой, точно так же, как у вас возникла новая проблема после исправления той, которую показал JBernardo, но это не значит, что вам не нужно решать эту проблему. исправить. - person abarnert   schedule 29.03.2013