2017-09-09 13 views
1

を読んだとき、私は次のスクリプトは、EOFError例外をスローせずに動作させることはできません。紛争() - 例外EOFError:EOF行

#!/usr/bin/env python3 

import json 
import sys 

# usage: 
# echo '[{"testname": "testval"}]' | python3 test.py 

myjson = json.load(sys.stdin) 
print(json.dumps(myjson)) 

answer = input("> ") # BUG: EOFError: EOF when reading a line 
print(answer) 

私はこの質問どれを読みました関連しているようです:Python STDIN User Input Issue

私は標準バッファーをクリアする必要があると私は言うと思いますか?しかし、私はprint(sys.stdin.readline())が改行を出力していて、EOFErrorがまだそこに残っているので、どうしてわからないのですか?

sys.stdin.flush()メソッド(この質問にある:Usage of sys.stdout.flush() method)を使ってみましたが、正式なドキュメント(3.6)で見つけることができなかったので、私はまだ理解しません。私はプログラマーでもCS教育やバックグラウンドも持っていないことに注意してください。私は、私の、それ以外の場合は、技術的でない作業の一部を自動化するためのスクリプトを書いています。だから、あなたが良い初心者を知っていれば、stdin/stdoutがPythonのシェルでどのように動作するかを再考してください。

+0

'json.load(sys.stdinをは)' STDINで使用可能なすべてのデータを消費します。読んで残るものは何もないので、EOFです。 – melpomene

答えて

1

パイプ入力では、Pythonはsys.stdinをFIFOとしてオープンしています。それ以外の場合、Pythonはsys.stdinを/dev/ttyまたは同等のものに開きます。

あなたはでこれを確認することができます。

import os,sys,stat 
print("isatty():", sys.stdin.isatty()) 
print("isfifo():", stat.S_ISFIFO(os.fstat(0).st_mode)) 

実行をこの二回、配管一度データでは、一度ではありません。

私が取得:

$ echo "Test" | ./test2.py 
isatty(): False 
isfifo(): True 

$ ./test2.py 
isatty(): True 
isfifo(): False 

FIFOのsys.stdinをがに開放されているので、だからあなたのEOFが発生したが空です。

ただし、sys.stdinを/dev/ttyに再度開くことができます。正常に動作します

j = json.load(sys.stdin) 
print(j) 

sys.stdin = open("/dev/tty") 

answer = input("> ") 
print(answer) 

$ echo '{"key":"val"}' | python3 ./testjson.py 
{'key': 'val'} 
> testing 
testing 
+0

私は「プログラマーではない」部分を太字で書いておかなければなりません。何が起こっているのかを理解するために研究しなければならないことがたくさんありますが、それは完全に機能します。説明と解決に感謝します! – rmercier

+0

これを取得しないことについて心配しないでください(本当に)。この種のことはまれですが、それが起こると信じられないほど混乱します。 – jedwards

0

標準入力(標準入力)を実際に「クリア」することはできません。そこには読み込みが可能で、ファイルの最後まで読み込まれる多くの入力関数(EOF、または標準入力の終り)があります。 「フラッシュ」操作は標準出力用です。

あなたの場合、json.load(sys.stdin)の操作はの全体を読み取って終了します(それ以降は閉じます)。その時点で、これ以上の入力は利用できません。

入力データを読み込み、ユーザーからの対話型入力が必要な場合は、ファイルからデータを読み込み、対話型ユーザー入力にのみ標準入力を使用することを検討してください。

+0

このthouroughの説明をありがとう! JSON文字列をstdoutにエクスポートするサードパーティのプログラムの後に実行する必要のあるスクリプトを作成しています。このサードパーティ製プログラムの動作を変更することはできません(たとえば、JSONをファイルに書き込むなど)。しかし、私はまた、ユーザーが手動でいくつかのJSON dictsを受け入れ、他の人を捨てる必要があります。 Pythonのようなことをする方法はありませんか? – rmercier

+0

おそらく、サードパーティ製のスクリプトのJSON出力を一時ファイルにパイプし、そのファイルをプログラムに渡すことがあります。一般的には、ファイルを読み込んだり、ユーザの入力をPythonやその他の言語で読むのに標準入力を使用することはできません。 – payne

関連する問題