2012-06-08 6 views
5

この練習をしながら、私は問題に遭遇しました。Pythonでは、ファイルを開いて1行で読むことができますが、その後もファイルを閉じることができますか?

from sys import argv 
from os.path import exists 

script, from_file, to_file = argv 
print "Copying from %s to %s" % (from_file, to_file) 

# we could do these two on one line too, how? 
input = open(from_file) 
indata = input.read() 

print "The input file is %d bytes long" % len(indata) 
print "Does the output file exist? %r" % exists(to_file) 
print "Ready, hit RETURN to continue, CTRL-C to abort." 

raw_input() 

output = open(to_file, 'w') 
output.write(indata) 
print "Alright, all done." 
output.close() 
input.close() 

# we could do these two on one line too, how?は私を混乱させます。これは私が望んだ道を行っ

indata = open(from_file).read() 

が、それは削除するために私を必要とします:私が思い付くことができる唯一の答えはなかった入力変数がもう存在しない

input.close() 

として。どうしたら、このクローズ操作を実行できますか?

どうすれば解決できますか?

+0

..私は、彼はあなたが後何であったかと思い

in_file = open(from_file); indata = in_file.read() 

すなわち

既存のコードの行の間にセミコロンを使用するには、あなたにみんなありがとう。気分がよくなりました。 @ Paul D. Waite私の質問を編集していただきありがとうございます。今ははるかに明確です。 – yoonsi

+0

ようこそ。他の人が質問の要点を知ることはしばしば簡単です。おそらく –

答えて

14

pythonでリソースを操作するための好ましい方法は、context managersを使用することです:

with open(infile) as fp: 
    indata = fp.read() 

with文は、リソースを閉鎖し、クリーンアップの世話をします。

あなたしたい場合は1行にそれを書くことができます:

with open(infile) as fp: indata = fp.read() 

をしかし、これはpythonで悪いスタイルと考えられています。

またwithブロック内の複数のファイルを開くことができます。私のpythonを学び始めたとき

with open(input, 'r') as infile, open(output, 'w') as outfile: 
    # use infile, outfile 

おかしいは十分に、私は戻ってexactly the same questionを尋ねました。

+0

良いスタイルは助言しますが、1行ではないので質問に答えません。 – Junuxx

+0

@ thg435、それはスタンドアウェイではありません!ちょうどファイルオブジェクトはContext Managerインタフェースを実装しています。 – astynax

+0

@astynax:はい、「preffered」がよりよく聞こえます。 – georg

0

スクリプトが完了すると、ファイルは自動的かつ安全に閉じられます。

+3

しかし、これに頼るのは本当に悪い考えです。なぜなら、時間の経過とともに多数のファイルを開く必要がある大規模なプログラムでは役に立たないからです。 Refcounting *はあなたを救うかもしれませんが、あなたはCPythonに縛られています。例えば、PyPyがより良いGCを持っているのでPyPy上で実行することでプログラムを3倍速くすることはできません。合理的にすぐにリソースを解放することに慣れてください。それは本当に難しいことではありません。 -1 – delnan

+0

Refcountingで保存しても、自動的に閉じられる各ファイルのPython 3.2で 'ResourceWarning'を取得します。 –

2
with open(from_file, 'r') as f: 
    indata = f.read() 

# outputs True 
print f.closed 
2

あなたはinputがためだけの名前であることを理解することは、運動と考えるべきかopenリターンではなく、あなたがべきそれを短くする方法を行うためのアドバイスなど。

この特定のケースでは、正しく識別された問題はあまり問題ではない - あなたのスクリプトはかなり短時間で終了するので、開いたファイルはかなり早く閉鎖されます。しかし、これは必ずしも当てはまるわけではありません。そして、ファイルの終了を保証する通常の方法は、withステートメントを使用することです。このステートメントは、Pythonを続行するときにわかります。

0

次のPythonコードはあなたの目標を達成します。

from contextlib import nested 

with nested(open('input.txt', 'r'), open('output.txt', 'w')) as inp, out: 
    indata = inp.read() 
    ... 
    out.write(out_data) 
+2

最近のPythonのバージョンでは 'contextlib.nested'は無意味です。 – delnan

+3

@delnan 2つのファイルを開くために 'contextlib.nested()'が使用されないようにしてください。 - 2番目のファイルを開くときにエラーが発生した場合、最初のファイルは閉じられません。これは文書化されたバグであり、新しい 'with'構文の代わりに推奨されなくなった理由の1つです。 –

+0

@Lattyware、情報ありがとうございます。私は心に留めておきます。 – astynax

0

だけ

関連する問題