web-dev-qa-db-ja.com

読み取りを開き、1行のコードでファイルを閉じます

今私は使用します:

pageHeadSectionFile = open('pagehead.section.htm','r')
output = pageHeadSectionFile.read()
pageHeadSectionFile.close()

しかし、コードの見栄えを良くするために、次のことができます。

output = open('pagehead.section.htm','r').read()

上記の構文を使用する場合、ファイルを閉じてシステムリソースを解放するにはどうすればよいですか?

104
1qazxsw2

本当に閉じる必要はありません-Pythonはガベージコレクション中またはプログラム終了時に自動的に閉じます。しかし、@ delnanが指摘したように、さまざまな理由で明示的に閉じることをお勧めします。

したがって、短く、シンプルで明示的に保つためにできること:

with open('pagehead.section.htm','r') as f:
    output = f.read()

今では2行でかなり読みやすいと思います。

167
Tim Pietzcker

Python標準ライブラリ Pathlib モジュールはあなたが探していることをします:

Path('pagehead.section.htm').read_text()

パスをインポートすることを忘れないでください:

jsk@dev1:~$ python3
Python 3.5.2 (default, Sep 10 2016, 08:21:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pathlib import Path
>>> (Path("/etc") / "hostname").read_text()
'dev1.example\n'

Python 27にバックポートインストール pathlib または pathlib2

37

CPythonを使用すると、ファイルオブジェクトはすぐにガベージコレクションされるため、行が実行された直後にファイルが閉じられます。ただし、次の2つの欠点があります。

  1. CPythonとは異なるPython実装では、多くの場合、ファイルはすぐに閉じられるのではなく、後で制御できなくなります。

  2. Python 3.2以降では、有効にするとResourceWarningがスローされます。

1行追加して投資する方が良い:

with open('pagehead.section.htm','r') as f:
    output = f.read()

これにより、すべての状況でファイルが正しく閉じられます。

19
Sven Marnach

これを行うために特別なライブラリをインポートする必要はありません。

通常の構文を使用すると、ファイルを読み取り用に開いてから閉じます

with open("/etc/hostname","r") as f: print f.read() 

または

with open("/etc/hosts","r") as f: x = f.read().splitlines()

行を含む配列xが得られ、次のように出力できます:

for line in x: print line

これらのワンライナーは、メンテナンスに非常に役立ちます-基本的に自己文書化。

13
SDsolar

できることは、withステートメントを使用することです。

>>> with open('pagehead.section.htm', 'r') as fin:
...     output = fin.read()

withステートメントは、コードに何か悪いことが起こった場合でも、指定されたオブジェクトの__exit__関数を呼び出すように注意します。 try... finally構文に近いです。 openによって返されるオブジェクトの場合、__exit__はファイルのクローズに対応します。

このステートメントはPython 2.6で導入されました。

9
Joël

ilio :(インラインio)を使用:

ファイルopen()、read()、close()の代わりに1つの関数呼び出しのみ。

from ilio import read

content = read('filename')
5
iman
with open('pagehead.section.htm')as f:contents=f.read()
3
user7050005

ログファイルでgrepしたものを囲むいくつかの行を取得する必要があるとき、私は頻繁にこのようなことをします。

$ grep -n "xlrd" requirements.txt | awk -F ":" '{print $1}'
54

$ python -c "with open('requirements.txt') as file: print ''.join(file.readlines()[52:55])"
wsgiref==0.1.2
xlrd==0.9.2
xlwt==0.7.5
0
Matthew Purdon

暖かくてあいまいな感じがしたい場合は、withを使用します。

python 3.6の場合、これら2つのプログラムをIDLEの新たなスタートの下で実行し、次のランタイムを提供しました。

0.002000093460083008  Test A
0.0020003318786621094 Test B: with guaranteed close

それほど違いはありません。

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test A for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __== '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: A: no 'with;
    c=[]
    start_time = time.time()
    c = open(inTextFile).read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

出力:

OK, starting program...
--- 0.002000093460083008 seconds ---
OK, program execution has ended.

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test B for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __== '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: B: using 'with'
    c=[]
    start_time = time.time()
    with open(inTextFile) as D: c = D.read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

出力:

OK, starting program...
--- 0.0020003318786621094 seconds ---
OK, program execution has ended.
0
CopyPasteIt

more_itertools.with_iter を使用すると、同等のoutputを1行で開いて読み取り、閉じて割り当てることができます(importステートメントを除く)。

import more_itertools as mit


output = "".join(line for line in mit.with_iter(open("pagehead.section.htm", "r")))

可能ですが、ファイルの内容を変数に割り当てる以外の別のアプローチ、つまり遅延反復を探します-これは、従来のwithブロックを使用するか、上記の例でjoin()を削除することで実行できますoutputを繰り返します。

0
pylang