このコードには複数の問題があります。
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
、回線に pingを実行して、これを修正します。
最後に、これらの問題をすべて解決したとしても、何もする前に永遠に待つ必要があります。readlines
行の a を返しますlist
。これを実行できる唯一の方法は、今後オンになるすべての行を読み取ることですstdin
。これらの行をすべて読むまで、ループを開始することさえできません。
標準入力がファイルの場合、それはファイルの終了時に発生するので、それほどひどいものではありません。しかし、標準入力が Windows のコマンド プロンプトの場合、コマンド プロンプトは決して終了しません。* したがって、これには永遠に時間がかかります。行のリストを待つのに永遠にかかるため、行のリストの処理を開始することはできません。
解決策は、使用しないことreadlines()
です。readlines()
本当に、何かを呼び出すかどうかにかかわらず、正当な理由はありstdin
ません。readlines
動作するものはすべて、それが与えるのと同じように、すでに行でいっぱいのイテラブルです。ただし、それは「怠惰」であることを除いて: 一度にすべての行を待って与えるのではなく、一度に 1 行ずつ与えることができます。(そして、本当にリストが必要な場合でも、代わりに実行してください。)list
readlines
list(f)
f.readlines()
したがって、代わりにfor line in sys.stdin.readlines():
、単に実行しますfor line in sys.stdin:
(または、明示的なループを完全に置き換えて、mgilsonの回答のように一連のイテレータ変換を使用することをお勧めします。)
JBernardo、Wing Tang Wong などが提案した修正はすべて正しく、必要です。どれも問題を解決できなかった理由は、4 つのバグがあり、1 つを修正したとしても、コードがまだ機能しないためです。プログラミングにおいて「うまくいかない」という数値が役に立たないのはまさにそのためであり、実際に何がうまくいかないのかをデバッグして、自分が進歩しているかどうかを知る必要があります。
stdin
* 私は決して終わらないことについて少し嘘をつきました. control-Z を入力すると (その後に改行が必要な場合とそうでない場合があります)、stdin
終了します。しかし、割り当てがユーザーが「quit」と入力するとすぐに終了するようにする場合 < ユーザーが「quit」と入力してから戻るときにのみ終了するものを入れる場合、control-Z、return はおそらく成功したとは見なされません。