歴史的に私はpython
のファイルを読み取るために常に以下を使用しました:
_with open("file", "r") as f:
for line in f:
# do thing to line
_
これはまだ推奨されるアプローチですか?以下を使用することに欠点はありますか?
_from pathlib import Path
path = Path("file")
for line in path.open():
# do thing to line
_
私が見つけたほとんどの参照は、ファイルを明示的に閉じる必要がないため、ファイルを開くためにwith
キーワードを使用しています。これは、ここでの反復子アプローチに適用できますか?
Path
オブジェクトはファイルシステムパスを操作するためのものであることに注意してください。 Pythonの built-in library と同様に、- open メソッドがありますが、Pathオブジェクトにはcloseはありません。
.close
は、組み込み open またはPathオブジェクトのopenメソッドを使用して返されるファイルハンドルにあります。
>>> from pathlib import Path
>>> p=Path(some_file)
>>> p
PosixPath('/tmp/file')
そのPathオブジェクトは、組み込みのopen関数またはPathオブジェクトのopenメソッドのいずれかで開くことができます。
>>> fh=open(p) # open built-in function
>>> fh
<_io.TextIOWrapper name='/tmp/file' mode='r' encoding='UTF-8'>
>>> fh.close()
>>> fh=p.open() # Path open method which aliases to os.open
>>> fh
<_io.TextIOWrapper name='/tmp/file' mode='r' encoding='UTF-8'>
>>> fh.close()
Githubのpathlib のソースコードを見ると、pathlib
の作成者が独自のコードでどのように行うかを確認できます。
私が観察しているのは、3つのことの1つです。
最も一般的なのは、with
を使用することです。
from pathlib import Path
p=Path('/tmp/file')
#create a file
with p.open(mode='w') as fi:
fi.write(f'Insides of: {str(p)}')
# read it back and test open or closed
with p.open(mode='r') as fi:
print(f'{fi.read()} closed?:{fi.closed}')
# prints 'Insides of: /tmp/file closed?:False'
ご存知のように、with
ブロックの最後に__exit__
メソッドが呼び出されます。ファイルの場合は、ファイルが閉じていることを意味します。これは、pathlib
ソースコードで最も一般的な方法です。
2番目に、pathlibオブジェクトがエントリと終了ステータス、および開いているファイルと閉じているファイルのフラグを保持していることをソースで確認することもできます。ただし、os.close
関数は明示的に呼び出されません。そのステータスは.closed
アクセサで確認できます。
fh=p.open()
print(f'{fh.read()} closed?:{fh.closed}')
# prints Insides of: /tmp/file closed?:False
# fi will only be closed when fi goes out of scope...
# or you could (and should) do fh.close()
with p.open() as fi:
pass
print(f'closed?:{fi.closed}')
# fi still in scope but implicitly closed at the end of the with bloc
# prints closed?:True
3番目に、cPythonでは、ファイルハンドルが範囲外になると、ファイルが閉じます。これは移植性がなく、信頼できる「良い習慣」とは考えられていませんが、一般的にはそうです。 pathlibソースコードにこのインスタンスがあります。
Pathlib
は、ファイルシステムパスを操作するためのオブジェクト指向の方法です。
pathlibモジュールを使用してファイルを開く推奨される方法は、コンテキストマネージャーを使用することです。
_p = Path("my_file.txt")
with p.open() as f:
f.readline()
_
これにより、使用後にファイルを確実に閉じることができます。
あなたが提供した両方の例では、ファイルを開くのでファイルを閉じませんinplace。
p.open()
はファイルオブジェクトを返すため、次のように割り当てて属性closed
を確認することでこれをテストできます。
_from pathlib import Path
path = Path("file.txt")
# Open the file pointed by this path and return a file object, as
# the built-in open() function does.
f = path.open()
for line in f:
# do some stuff
print(f.closed) # Evaluates to False.
_
まだ言及されていないもの:やりたいことがいくつかのテキスト(またはバイト)の読み取りまたは書き込みである場合、pathlibを使用するときにコンテキストマネージャーを明示的に使用する必要はなくなりました。
>>> import pathlib
>>> path = pathlib.Path("/tmp/example.txt")
>>> path.write_text("hello world")
11
>>> path.read_text()
'hello world'
>>> path.read_bytes()
b'hello world'
ファイルを開いて行を繰り返す場合は、コンテキストマネージャをopen
と一緒に使用するのと同じ理由で ドキュメントの表示 と同じ理由で、引き続きwithステートメントを使用する必要があります。
>>> with path.open() as f:
... for line in f:
... print(line)
...
hello world