私の質問は、open()
を使用したPythonのファイル入力に関連しています。 3行のテキストファイル_mytext.txt
_があります。このファイルで2つのことを行おうとしています。行の印刷と行数の印刷です。
私は次のコードを試しました:
_input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
print line
for line in input_file:
count_lines += 1
print 'number of lines:', count_lines
_
結果:3行は正しく印刷されますが、「行数:0」(3ではなく)が印刷されます
私はそれを解決する2つの方法を見つけて、_3
_を印刷するようにしました:
1)2つではなく1つのループを使用します
_input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
print line
count_lines += 1
print 'number of lines:', count_lines
_
2)最初のループの後、input_fileを再度定義します
_input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
print line
input_file = open('mytext.txt', 'r')
for line in input_file:
count_lines += 1
print 'number of lines:', count_lines
_
私には、定義_input_file = ...
_は、ループに使用した後に削除されたかのように、1つのループに対してのみ有効であるように思われます。しかし、私はなぜ、おそらく100%明確ではないのか、variable = open(filename)
がPythonでどのように扱われるのかを理解していません。
ちなみに、この場合はループを1つだけ使用する方が良いことがわかります。しかし、私はこの質問を明確にする必要があると感じています。なぜなら、それを利用できる/しなければならない場合があるからです。
ファイルハンドルは反復子です。ファイルを反復処理した後、ポインターはEOF(ファイルの終わり)に配置され、イテレーターはStopIterationを発生させ、ループを終了します。ポインタはEOFにあります。StopIterationを発生させて終了します。2番目のループでゼロをカウントする理由です。input_file.seek(0)
でファイルポインタを巻き戻すことができます。
ただし、同じループで行をカウントするとI/Oの効率が上がります。そうしないと、行をカウントするためにディスクからファイル全体をもう一度読み込む必要があります。これは非常に一般的なパターンです。
with open('filename.ext') as input_file:
for i, line in enumerate(input_file):
print line,
print "{0} line(s) printed".format(i+1)
Python 2.5では、ファイルオブジェクトに__enter__
および__exit__
は、 with
ステートメントインターフェイス に対処します。これは次のようなものの構文糖衣です:
input_file = open('filename.txt')
try:
for i, line in enumerate(input_file):
print line,
finally:
input_file.close()
print "{0} line(s) printed".format(i+1)
CPythonはガベージコレクションを取得するとファイルハンドルを閉じると思いますが、これがすべての実装に当てはまるかどうかはわかりません。リソースハンドルを明示的に閉じることをお勧めします。
以下を使用できない理由がありますか?
input_file = open('mytext.txt', 'r')
count_lines = 0
for line in input_file:
print line
count_lines += 1
print 'number of lines:', count_lines
Openによって返されるものは、ファイルオブジェクトです。ファイルオブジェクトは、ループするときに自身の内部位置を追跡するため、最初に試行したことを実行するには、手動で最初に巻き戻す必要があります。それ自体では実行されません。
2つのループの間にinput_file.seek(0)
を追加してみてください。これにより、ファイルが先頭に巻き戻されるので、もう一度ループすることができます。
私はあなたが望むモジュールファイル入力を薄くします。
if __name__ == "__main__":
for line in fileinput.input():
if fileinput.isfirstline():
print("current file: %s" % fileinput.filename())
print("line number: %d, current file number: %d" %
(fileinput.lineno(), fileinput.filelineno()))