Python Language
ファイルとフォルダのI / O
サーチ…
前書き
データの格納、読み込み、または通信に関しては、オペレーティングシステムのファイルを操作することは、Pythonでは必要かつ容易です。ファイルの入出力に複雑なオブジェクトの読み書きが必要な他の言語とは異なり、Pythonはファイルを開く、読み書きする、および閉じるためのコマンドが必要なプロセスを単純化します。このトピックでは、Pythonがオペレーティングシステム上のファイルとどのようにインターフェイスできるかについて説明します。
構文
- file_object = open(ファイル名[、access_mode] [、バッファリング])
パラメーター
パラメータ | 詳細 |
---|---|
ファイル名 | ファイルへのパス、またはファイルが作業ディレクトリにある場合は、ファイルのファイル名 |
アクセスモード | ファイルのオープン方法を決定する文字列値 |
バッファリング | オプションのラインバッファリングに使用される整数値 |
備考
クロスプラットフォームエンコーディング地獄の回避
Pythonの組み込みopen()
を使用する場合、コードをクロスプラットフォームで実行する場合は、常にencoding
引数を渡すことがベストプラクティスです。この理由は、システムのデフォルトエンコーディングがプラットフォームによって異なります。
linux
システムは実際にutf-8
をデフォルトとして使用しますが、これはMACとWindowsでは必ずしも当てはまりません 。
システムのデフォルトのエンコーディングを確認するには、次のようにしてください:
import sys
sys.getdefaultencoding()
任意のPythonインタプリタから。
したがって、作業している文字列が、あなたが思っているものとしてエンコードされていることを確認し、プラットフォーム間の互換性を確保するために、常にエンコードを分離することが賢明です。
with open('somefile.txt', 'r', encoding='UTF-8') as f:
for line in f:
print(line)
ファイルモード
mode
パラメータで指定されたファイルを開くことができるモードはいくつかあります。これらには、
'r'
- 読み取りモード。デフォルト。それは、あなたがそれを変更するのではなく、ファイルを読むことだけを許します。このモードを使用する場合、ファイルが存在する必要があります。'w'
- 書き込みモード。存在しない場合は新しいファイルを作成し、それ以外の場合はファイルを消去して書き込みを許可します。'a'
- 追加モード。ファイルの最後にデータを書き込みます。ファイルを消去せず、ファイルはこのモードで存在する必要があります。'rb'
- バイナリでの読み取りモード。これはr
似ていますが、読み取りはバイナリモードで強制されます。これもデフォルトの選択です。'r+'
- 読み取りモードと書き込みモードを同時に行います。これにより、r
とw
を使わなくても、同時にファイルを読み書きすることができます。'rb+'
- バイナリでの読み書きモード。データがバイナリであることを除いてr+
と同じです。'wb'
- バイナリ形式の書き込み。データを除いてw
と同じですが、バイナリです。'w+'
- 書き込みモードと読み取りモード。r+
と全く同じですが、ファイルが存在しない場合は、新しいファイルが作成されます。それ以外の場合、ファイルは上書きされます。'wb+'
- バイナリモードでの書き込みと読み取りモード。w+
と同じですが、データはバイナリです。'ab'
- バイナリモードで追加します。データがバイナリでa
点を除いて、a
と同様です。'a+'
- 追加モードと読み取りモード。ファイルが存在しない場合は、新しいファイルを作成するので、w+
と同様です。それ以外の場合、ファイルポインタはファイルの末尾にあります(存在する場合)。'ab+'
- バイナリで追加モードと読み取りモード。データがバイナリであることを除いて、a+
と同じです。with open(filename, 'r') as f: f.read() with open(filename, 'w') as f: f.write(filedata) with open(filename, 'a') as f: f.write('\n' + newdata)
r | r + | w | w + | a | a + | |
---|---|---|---|---|---|---|
読む | ✔ | ✔ | ✘ | ✔ | ✘ | ✔ |
書きます | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
ファイルを作成する | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ |
ファイルを消去する | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ |
最初の位置 | 開始 | 開始 | 開始 | 開始 | 終わり | 終わり |
Python 3は、 exclusive creation
ための新しいモードを追加しました。誤って切り詰めたり上書きしたり、既存のファイルを上書きしたりすることはありません。
-
'x'
- 排他的な作成のために開いて、ファイルが既に存在する場合はFileExistsError
ます -
'xb'
- バイナリで排他的な作成モードを開く。データがバイナリであることを除いて、x
と同じです。 -
'x+'
- 読み書きモード。ファイルが存在しない場合は、新しいファイルを作成するので、w+
と同様です。それ以外の場合、FileExistsError
ます。 -
'xb+'
- 書き込みと読み取りのモード。x+
と全く同じですが、データはバイナリです
バツ | x + | |
---|---|---|
読む | ✘ | ✔ |
書きます | ✔ | ✔ |
ファイルを作成する | ✔ | ✔ |
ファイルを消去する | ✘ | ✘ |
最初の位置 | 開始 | 開始 |
あなたのファイルオープンコードをもっとpythonicな方法で書くことができます:
try:
with open("fname", "r") as fout:
# Work with your open file
except FileExistsError:
# Your error handling goes here
Python 2では、あなたは
import os.path
if os.path.isfile(fname):
with open("fname", "w") as fout:
# Work with your open file
else:
# Your error handling goes here
ファイルを1行ずつ読む
ファイルを1行ずつ繰り返し処理する最も簡単な方法は次のとおりです。
with open('myfile.txt', 'r') as fp:
for line in fp:
print(line)
readline()
は、行ごとの繰り返しに対してより詳細な制御を可能にします。下の例は、上記の例と同じです。
with open('myfile.txt', 'r') as fp:
while True:
cur_line = fp.readline()
# If the result is an empty string
if cur_line == '':
# We have reached the end of the file
break
print(cur_line)
forループ反復子とreadline()を一緒に使用することは悪い習慣とみなされます。
より一般的には、 readlines()
メソッドは、ファイルの行の繰り返し可能なコレクションを格納するために使用されます。
with open("myfile.txt", "r") as fp:
lines = fp.readlines()
for i in range(len(lines)):
print("Line " + str(i) + ": " + line)
これは次のように表示されます。
0行目:こんにちは
1行目:世界
ファイルの完全な内容を取得する
ファイルI / Oの好ましい方法は、 with
キーワードを使用することです。これにより、読み取りまたは書き込みが完了するとファイルハンドルが確実に閉じられます。
with open('myfile.txt') as in_file:
content = in_file.read()
print(content)
または、手動でファイルを閉じる処理するために、あなたは見送る可能with
し、単に呼び出すclose
、自分自身を:
in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()
with
文を使用しないwith
、予期しない例外が発生した場合に備えて、誤ってファイルを開いたままにすることがあります。
in_file = open('myfile.txt', 'r')
raise Exception("oops")
in_file.close() # This will never be called
ファイルへの書き込み
with open('myfile.txt', 'w') as f:
f.write("Line 1")
f.write("Line 2")
f.write("Line 3")
f.write("Line 4")
myfile.txt
を開くと、その内容は次のようになります:
ライン1ライン2ライン3ライン4
Pythonは自動的に改行を追加しませんので、手動で行う必要があります:
with open('myfile.txt', 'w') as f:
f.write("Line 1\n")
f.write("Line 2\n")
f.write("Line 3\n")
f.write("Line 4\n")
ライン1
2行目
3行目
4行目
テキストモードで開いたファイルを書き込むときに、行終端os.linesep
としてos.linesep
を使用しないでください(デフォルト)。代わりに\n
使用してください。
エンコードを指定する場合は、 encoding
パラメータをopen
関数に追加するだけです。
with open('my_file.txt', 'w', encoding='utf-8') as f:
f.write('utf-8 text')
また、printステートメントを使用してファイルに書き込むこともできます。この仕組みはPython 2とPython 3では異なっていますが、そのコンセプトは画面に出力される出力を取り込んでファイルに送るという点で同じです。
with open('fred.txt', 'w') as outfile:
s = "I'm Not Dead Yet!"
print(s) # writes to stdout
print(s, file = outfile) # writes to outfile
#Note: it is possible to specify the file parameter AND write to the screen
#by making sure file ends up with a None value either directly or via a variable
myfile = None
print(s, file = myfile) # writes to stdout
print(s, file = None) # writes to stdout
Python 2では、あなたは
outfile = open('fred.txt', 'w')
s = "I'm Not Dead Yet!"
print s # writes to stdout
print >> outfile, s # writes to outfile
write関数を使用するのとは異なり、print関数は改行を自動的に追加します。
あるファイルの内容を別のファイルにコピーする
with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
for line in in_file:
out_file.write(line)
-
shutil
モジュールの使用:
import shutil
shutil.copyfile(src, dst)
ファイルまたはパスが存在するかどうかを確認する
EAFPコーディングスタイルを採用し、それを開こtry
する。
import errno
try:
with open(path) as f:
# File exists
except IOError as e:
# Raise the exception if it is not ENOENT (No such file or directory)
if e.errno != errno.ENOENT:
raise
# No such file or directory
これにより、別のプロセスがファイルをチェックの間で削除した場合と、チェックが使用されたときに競合状態が回避されます。この競合状態は、次の場合に発生する可能性があります。
os
モジュールの使用:import os os.path.isfile('/path/to/some/file.txt')
pathlib
をpathlib
:import pathlib path = pathlib.Path('/path/to/some/file.txt') if path.is_file(): ...
指定されたパスが存在するかどうかを確認するには、上記のEAFPプロシージャに従うか、パスを明示的にチェックします。
import os
path = "/home/myFiles/directory1"
if os.path.exists(path):
## Do stuff
ディレクトリツリーをコピーする
import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)
宛先ディレクトリはすでに存在してはいけません 。
ファイルの反復処理(再帰的に)
サブディレクトリを含むすべてのファイルを反復するには、os.walkを使用します。
import os
for root, folders, files in os.walk(root_dir):
for filename in files:
print root, filename
root_dirは "。"にすることができます。現在のディレクトリから開始するか、または他のどのパスから開始するかを指定します。
ファイルに関する情報を取得したい場合は、より効率的なos.scandirメソッドを使用することもできます:
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)
ある範囲の行の間でファイルを読む
だから、ファイルの特定の行の間だけを反復したいとしましょう
あなたはitertools
を利用することができます
import itertools with open('myfile.txt', 'r') as f: for line in itertools.islice(f, 12, 30): # do something here
これは、pythonの索引付けが0から始まるので、13行目から20行目まで続きます。したがって、行番号1は0として索引付けされます
同様にnext()
キーワードを使って余分な行を読むこともできます。
また、ファイルオブジェクトを反復可能なものとして使用している場合は、ファイルを走査する2つの手法を混在させないため、ここではreadline()
文を使用しないでください
mmapを使ったランダムファイルアクセス
mmap
モジュールを使用すると、ファイルをメモリにマッピングすることで、ファイル内の場所にランダムにアクセスすることができます。これは、通常のファイル操作を使用する代わりの方法です。
import mmap
with open('filename.ext', 'r') as fd:
# 0: map the whole file
mm = mmap.mmap(fd.fileno(), 0)
# print characters at indices 5 through 10
print mm[5:10]
# print the line starting from mm's current position
print mm.readline()
# write a character to the 5th index
mm[5] = 'a'
# return mm's position to the beginning of the file
mm.seek(0)
# close the mmap object
mm.close()
ファイル内のテキストの置換
import fileinput
replacements = {'Search1': 'Replace1',
'Search2': 'Replace2'}
for line in fileinput.input('filename.txt', inplace=True):
for search_for in replacements:
replace_with = replacements[search_for]
line = line.replace(search_for, replace_with)
print(line, end='')
ファイルが空であるかどうかの確認
>>> import os
>>> os.stat(path_to_file).st_size == 0
または
>>> import os
>>> os.path.getsize(path_to_file) > 0
ただし、ファイルが存在しない場合は、両方とも例外がスローされます。このようなエラーが発生しないようにするには、次のようにします。
import os
def is_empty_file(fpath):
return os.path.isfile(fpath) and os.path.getsize(fpath) > 0
bool
値を返します。