「Pythonの基礎 - ファイル」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
514行目: 514行目:
   
   
  print(p.read_text())
  print(p.read_text())
p.close()
   
   
  # 出力
  # 出力
519行目: 521行目:
  Honda
  Honda
  </syntaxhighlight>
  </syntaxhighlight>
<br>
以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルの内容を読み込み、<br>
改行文字を区切り文字として、行ごとに要素として追加したリストを作成している。<br>
<syntaxhighlight lang="python">
import pathlib
p = pathlib.Path('./test/name.txt')
data = p.read_text()
print(data.split('\n'))
p.close()
</syntaxhighlight>
<br>
==== バイナリファイルの読み書き ====
バイナリファイルに対してデータを読み書きする場合、<code>Path</code>クラスの<code>read_bytes</code>メソッドおよび<code>write_bytes</code>メソッドを使用する。<br>
<br>
バイナリファイルにデータを読み込む場合、パスが示すファイルの内容をbytesオブジェクトで取得する。<br>
<syntaxhighlight lang="python">
Path.read_bytes()
</syntaxhighlight>
<br>
バイナリファイルにデータを書き込む場合、パスが示すファイルに対して、引数で指定したbytesオブジェクトを書き込む。<br>
<syntaxhighlight lang="python">
Path.write_bytes(data)
</syntaxhighlight>
<br>
以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルに対して、<br>
バイナリデータ(ABCDEFG)を書き込みした後、そのバイナリデータを読み込み標準出力に出力している。<br>
<syntaxhighlight lang="python">
import pathlib
p = pathlib.Path('./test/name.txt')
p.write_bytes(b'ABCDEFG')
data = p.read_bytes()
print(data)
p.close()
# 出力
b'ABCDEFG'
</syntaxhighlight>
<br>
また、1度に読み込むデータのバイト数を指定する場合は、従来の方法と同様、ファイルオブジェクトに対して、<code>read</code>メソッド等を使用する。<br>
詳細は、[[Pythonの基礎 - ファイル#バイナリファイル]]を参照すること。<br>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:Python]]
[[カテゴリ:Python]]

2021年11月21日 (日) 07:06時点における版

概要

Pythonでは、ローカルに保存されたファイルからデータを読み込んだり、ファイルへデータを書き込むことができる。
また、ディレクトリに含まれるファイルの一覧を取得したり、ディレクトリ名を変更したりすることもできる。


ファイルのオープン / クローズ

ファイルを開く

組み込み関数のopen関数を使用してファイルを開くことができる。

 open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)


第1引数は、開くファイル名を指定する。
正常に開くことができる場合、対応するファイルオブジェクトを返す。(ファイルオブジェクトは、第2引数で指定したモードにより異なる)
正常に開くことができない場合、例外OSErrorが送出される。

第2引数は、ファイルを開くモードを指定する。(デフォルトはテキストモード(t)のため、tを明示的に付加する必要はない)
バイナリモード(b)で読み込み権限や書き込み権限を付加する場合、r+bwbと指定する。

  • r
    読み込み用(ファイルが存在しない場合はエラー)
  • r+
    読み込みおよび書き込み用(ファイルが存在しない場合はエラー)
  • w
    書き込み用(ファイルの中身をクリア)
  • w+
    読み込みおよび書き込み用(ファイルの中身をクリア)
  • a
    書き込み用(ファイルの末尾に追加)
  • a+
    読み込みおよび書き込み用(ファイルの末尾に追加)
  • x
    書き込み用(ファイルが存在している場合はエラー)
  • x+
    読み込みおよび書き込み用(ファイルが存在している場合はエラー)
  • b
    バイナリモード
  • t
    テキストモード


第4引数は、使用する文字エンコーディングを指定する。
これは、テキストモードでのみ指定する。

  • ascii
  • cp932
  • euc_jp
  • shift_jis
  • utf-8 (utf_8)


エンコーディングを省略した場合は、現在のプラットフォームのデフォルトエンコーディングが使用される。
自身の環境でのデフォルトエンコーディングを確認するには、以下のソースコードを実行する。

 import locale
 
 locale.getpreferredencoding()


もし、UTF-8を使用して記述されたファイルを読み込む場合、encoding='UTF-8'のように引数に指定する。
なお、開くファイルが存在しない場合は、例外FileNotFoundErrorが発生する。

 f1 = open('myfile.txt', 'r')
 f2 = open('myfile.txt', 'w+')
 f3 = open('myfile.txt', 'r', encoding='UTF-8')
 f4 = open('myfile.txt', 'rb')


正常にファイルが開かれると、ファイルオブジェクトが返る。
ファイルオブジェクトのクラスは、open関数で使用したモードによって異なる。
例えば、テキストモードの場合はio.TextIOWrapper、バイナリモードの読み込みの場合はio.BufferedReader、バイナリモードの書き込みの場合はio.BufferedWriter
バイナリモードの読み書きの場合はio.BufferedRandomとなる。

  • r
    io.TextIOWrapper
  • r+
    io.TextIOWrapper
  • rb
    io.BufferedReader
  • r+b
    io.BufferedRandom
  • w
    io.TextIOWrapper
  • w+
    io.TextIOWrapper
  • wb
    io.BufferedWriter
  • w+b
    io.BufferedRandom
  • a
    io.TextIOWrapper
  • a+
    io.TextIOWrapper
  • ab
    io.BufferedWriter
  • a+b
    io.BufferedRandom
  • x
    io.TextIOWrapper
  • x+
    io.TextIOWrapper
  • xb
    io.BufferedWriter
  • x+b
    io.BufferedRandom


ファイルを閉じる

ファイルの使用後は、close関数を使用してファイルオブジェクトを閉じる。

 f = open('myfile.txt', 'r')
 # 処理1
 # 処理2
 f.close()


他の方法として、with文を使用してファイルを開く場合、使用後は自動的にファイルを閉じることができる。
どちらの方法でも、結果は同じになる。

 with open('myfile.txt', 'r') as f:
 # 処理1
 # 処理2


以下の例では、myfile.txtファイルの内容を読み込み画面に出力した後、ファイルオブジェクトを閉じている。
以下の内容のmyfile.txtファイルを作成する。

# myfile.txtファイル

Hello
World


 f = open('myfile.txt', 'r')
 
 data = f.read()
 print(data)
 
 f.close()



デキストファイルファイルの読み込み

全体を読み込む (readメソッド)

ファイルに含まれるテキストを全て読み込む場合、readメソッドを使用する。

 read(size=-1)


引数を指定しない場合、ファイルをEOF(ファイルの終端)まで読み込み、文字列として返す。
引数に最大文字数を指定する場合、指定した文字数分だけ読み込む。

なお、読み込むファイルの文字エンコードとopen関数で指定した文字エンコードが異なる場合、readメソッドを実行した時、例外UnicodeDecodeErrorが発生する。

以下の例では、プログラムと同階層のディレクトリにmyfile.txtファイル(UTF-8)を作成している。

 f = open('myfile.txt', 'r', encoding='UTF-8')
 
 data = f.read()
 print(data)
 
 f.close()


行単位で読み込む (readlineメソッド)

ファイルから1行ずつファイルの内容を読み込む場合、readlineメソッドを使用する。

readlineメソッドは、改行またはEOFまでファイルを読み込み、文字列として返す。
引数に最大文字数を指定する場合、指定した文字数分だけ読み込む。
ファイルの終端であるEOFまで読み込むと空の文字列を返す。

 readline(size=-1)


以下の例では、for文およびwhile文を使用して、ファイルの終端まで順にファイルの内容を読み込んでいる。

なお、readlinesメソッドの場合と同様、各行のデータには改行文字が含まれるため、
必要な場合は、print関数で最後に改行を行わないようにする、または、読み込んだデータの末尾から改行を取り除くこと。

 # for文を使用する場合
 f = open('myfile.txt', 'r', encoding='UTF-8')
 
 for data in f:
    print(data)               # 改行をそのまま出力する場合
    print(data.rstrip('\n'))  # 改行を取り除く場合
 
 f.close()
 
 
 # while文を使用する場合
 f = open('myfile.txt', 'r', encoding='UTF-8')
 
 while True:
    data = f.readline()
    if data == '':
       break
 
    print(data)               # 改行をそのまま出力する場合
    print(data.rstrip('\n'))  # 改行を取り除く場合
 
 f.close()


行単位で分割してリストとして取得する (readlinesメソッド)

readlinesメソッドを使用して、ファイル全体の読み込み後、読み込みしたデータを行単位で分割して、リストの要素として追加することができる。

readlinesメソッドは、引数に最大文字数を指定する場合、指定した文字数分だけ読み込む。

 readlines(hint=-1)


以下の例では、ファイルの内容を全て読み込み、行単位で分割してリストとして取得したデータを順に出力している。

print関数を使用して出力する場合、各行のデータには改行文字が含まれており、print関数では最後に自動的に改行をするようになっているため、改行が2回出力される。
そのため、print関数を使用して出力する場合、改行なしで出力する、または、出力するデータの末尾から改行を取り除くこと。

 f = open('myfile.txt', 'r')
 
 datalist = f.readlines()
 for data in datalist:
    print(data, end='')       # 改行なしで出力する
    print(data.rstrip('\n'))  # 文字列の末尾から改行を取り除く
 
 f.close()



テキストファイルの書き込み

テキストファイルへ書き込むためにファイルを開く場合、 open関数のモードとしてwaxのいずれかを指定する。

 f = open('myfile.txt', 'w')
 f = open('myfile.txt', 'a')
 f = open('myfile.txt', 'x')


wを指定する場合、対象のファイルが存在していない時はファイルを新規作成して書き込む。
ファイルが存在する時はファイルに上書きする。(既存のファイル内容は全て削除)

aを指定する場合、対象のファイルが存在していない時はファイルを新規作成して書き込む。
ファイルが存在する時は既存のファイル内容に追記して書き込む。

xを指定する場合、対象のファイルが存在しない時はファイルを新規作成して書き込む。
ファイルが存在する時は、例外FileExistsErrorが発生する。

書き込むファイルの文字エンコードが、ユーザの環境のデフォルトエンコーディングと異なる場合は、文字エンコードを指定する。

 f = open('myfile.txt', 'w', encoding='UTF-8')


書き込み / 上書き (wモード)

wモードでファイルを書き込む場合、ファイルが存在しない時はファイルを新規作成、ファイルが存在する時は上書きする。(既存のファイル内容は全て削除)

テキストファイルに書き込む場合は、writeメソッドを使用する。
writeメソッドの引数に、ファイルに書き込む文字列を指定する。

writeメソッドは最後に改行を書き込まないため、必要に応じて\nを合わせて書き込む。
標準では、\nを書き込むと自動的に利用しているプラットフォームに合わせて改行が書き込まれる。
例えば、MacOSの場合は\r、Windowsの場合は\r\nが書き込まれる。

 f = open('myfile.txt', 'w')
 
 f.write('こんにちは\n')
 
 f.close()


複数の文字列をまとめてファイルに書き込む場合は、writelinesメソッドを使用する。
引数には、文字列を要素としてリストを指定して、リストの要素を順にファイルに書き込む。

 f = open('myfile.txt', 'w', encoding='UTF-8')
 
 datalist = ['こんにちは\n', 'お元気ですか?\n', 'それではまた\n']
 f.writelines(datalist)
 
 f.close()


writelinesメソッドは自動的に改行を書き込まないため、必要に応じて、要素に格納する文字列に\nを記述する。
wモードの場合はファイルが存在しても上書きで書き込むため、open関数で指定した文字エンコードを使用してファイルに書き込む。(既存のファイルの文字エンコードは無視される)
そのため、文字エンコードが異なる場合でもエラーにはならない。

追記 (aモード)

aモードでファイルを追記する場合、ファイルが存在しない時はファイルを新規作成、ファイルが存在する時はファイルの最後に追記する。(既存の内容はそのまま)

ファイルに追記する場合は、wモードと同様、writeメソッド、または、writelinesメソッドを使用する。

 f = open('myfile.txt', 'a')
 
 f.write('こんにちは\n')
 
 datalist = ['お元気ですか?\n', 'それではまた\n']
 f.writelines(datalist)
 
 f.close()


※注意
既存のファイルに追記する時、ファイルの文字エンコードとopen関数の文字エンコードが異なる場合、
writeメソッドを実行する時はエラーは発生しないが文字化けするため注意すること。

 f = open('myfile.txt', 'a', encoding='UTF-8')
 
 f.write('それではまた\n')
 
 f.close()


ファイルを新規作成して書き込む (xモード)

xモードでファイルに書き込む場合、ファイルが存在しない場合はファイルを新規作成して書き込む。
ファイルが存在する場合は、open関数を実行した時点で例外FileExistsErrorが発生する。

ファイルに書き込む場合、wモードと同様、writeメソッド、またはwritelinesメソッドを使用する。

 f = open('myfile.txt', 'x', encoding='UTF-8')
 
 f.write('こんにちは\n')
 
 datalist = ['お元気ですか?\n', 'それではまた\n']
 f.writelines(datalist)
 
 f.close()



バイナリファイル

バイナリファイルを読み込む場合、open関数のモードとしてrbを指定する。

 f = open('myfile.dat', 'rb')


バイナリファイルのデータを読み込む場合、readメソッドを使用する。
readメソッドの引数には、読み込むバイト数を指定する。
引数を省略した場合は、EOFまでのデータを全て読み込み、bytesオブジェクトとして返す。

 read([size])


バイナリファイルへ書き込む場合、open関数のモードとしてwaxのいずれかにbを加えたwbabxbのいずれかを指定する。
なお、waxの違いについてはテキストファイルの場合と同様である。

 f = open('myfile.dat', 'wb')
 f = open('myfile.dat', 'ab')
 f = open('myfile.dat', 'xb')


バイナリファイルにデータを書き込む場合、writeメソッドを使用して、引数に指定したbytesオブジェクトをバイナリファイルに書き込む。

 f = open('myfile.dat', 'wb')
 f.write(b'ABCDEFG')
 f.close()
 
 f = open('myfile.dat', 'rb')
 data = f.read()
 print(data)
 f.close()
 
 # 出力
 b'ABCDEFG'


以下の例では、画像ファイルを1バイトずつ読み込み、読み込んだデータを新規作成したバイナリファイルに書き込んでいる。
ソースコードの実行後、ソースコードと同階層のディレクトリにSample2.pngファイルが生成される。

 fr = open('Sample1.png', 'rb')
 fw = open('Sample2.png', 'wb')
 
 while True:
    data = fr.read(1)
    if len(data) == 0:
       break
 
    fw.write(data)
 
 fw.close()
 fr.close()



ファイルの読み書き (pathlib)

Python3.4以降、pathlibモジュールが利用できる。
Pathクラスのインスタンスを生成した後、用意されたメソッドを使用してファイルの操作を行うことができる。

Pathクラスのインスタンスを作成する

Pathクラスのインスタンスを生成するには、以下のコンストラクタを使用する。

 class pathlib.Path(*pathsegments)


引数にファイルのパスを指定して、Pathクラスのインスタンスを生成する。
Pathクラスは、OSに応じてPathクラスのサブクラスであるpathlib.WindowsPathクラスまたはpathlib.PosixPathクラスのインスタンスが生成される。

 import pathlib
 
 path = './test/movie'
 p = pathlib.Path(path)
 
 type(p)


なお、pathlib.WindowsPathクラス、および、pathlib.PosixPathクラスのコンストラクタも存在するため、明示的にインスタンスを生成することもできる。
ただし、例えば、Windows環境において、pathlib.PosixPathクラスのインスタンスは生成できない。(例外NotImplementedErrorが発生する)

 class pathlib.PosixPath(*pathsegments)
 class pathlib.WindowsPath(*pathsegments)


 import pathlib
 
 path = './test/movie'
 wp = pathlib.WindowsPath(path)
 pp = pathlib.PosixPath(path)


ファイルを開く

pathlibモジュールを使用する場合は、Pathクラスのインスタンスを生成した後、openメソッドを使用してファイルオブジェクトを取得する。

第1引数には、ファイルを開くモードを指定する。指定できる値は、open関数と同様である。
第3引数には、使用する文字エンコードを指定する。これは、テキストモードでのみ指定する。指定できる値は、open関数と同様である。

 Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)


 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 
 f1 = p.open('r')
 f2 = p.open('w+')
 f3 = p.open('r', encoding='UTF-8')
 f4 = p.open('rb')


Pathクラスでは、ファイルオブジェクトを使用せずにファイルの読み書きを行うことができるメソッドが存在するが、一部使用できない機能もある。
その場合は、ファイルオブジェクトを取得した上で処理を行うこと。

ファイルを閉じる

ファイルを使用した後は、closeメソッドを使用してファイルオブジェクトを閉じる。

 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 f = p.open('r')
 
 # ...処理

 f.close()


他の方法として、with文を使用することにより、自動的にファイルを閉じることができる。

 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 with p.open('r') as f:
    # ...処理1
    # ...処理2


テキストファイルの読み込み

テキストファイルの全てを1度に読み込む場合、Pathクラスのread_textメソッドを使用する。

パスが示すファイルの内容をテキストとして取得する。省略可能な第1引数には、文字エンコードを指定することがきでる。
このメソッドは、ファイルオブジェクトを取得する必要がない。

 Path.read_text(encoding=None, errors=None)


 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 print(p.read_text())
 
 # 出力
 Yamada
 Andou
 Kuroki


なお、テキストファイルを行単位で読み込む場合、従来の方法と同様、ファイルオブジェクトに対してreadlineメソッド等を使用する。

 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 f = p.open('r')
 
 while True:
    data = f.readline()
    if data == '':
       break
 
    print (data.rstrip('\n'))
 
 # 出力
 Yamada
 Andou
 Kuroki


テキストファイルの書き込み

テキストファイルへデータを書き込む場合、Pathクラスのwrite_textメソッドを使用する。

第1引数は、書き込むデータを指定する。(パスが示すファイルへ書き込む)
第2引数には、省略可能であり、文字エンコーディングを指定する。

 Path.write_text(data, encoding=None, errors=None)


Pathクラスのwrite_textメソッドは、ファイルオブジェクトを取得する必要が無い。
なお、ファイルの書き込みは上書きで行われる。
また、ファイルが存在しない場合、新規作成した後でテキストの書き込みが行われる。
既存のファイルにファイル内容を追記する場合、従来の方法と同様、ファイルオブジェクトに対してwriteメソッド等を使用する。

 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 p.write_text('Suzuki\nHonda\n')
 
 print(p.read_text())
 
 p.close()
 
 # 出力
 Suzuki
 Honda


以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルの内容を読み込み、
改行文字を区切り文字として、行ごとに要素として追加したリストを作成している。

 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 data = p.read_text()
 
 print(data.split('\n'))
 
 p.close()


バイナリファイルの読み書き

バイナリファイルに対してデータを読み書きする場合、Pathクラスのread_bytesメソッドおよびwrite_bytesメソッドを使用する。

バイナリファイルにデータを読み込む場合、パスが示すファイルの内容をbytesオブジェクトで取得する。

 Path.read_bytes()


バイナリファイルにデータを書き込む場合、パスが示すファイルに対して、引数で指定したbytesオブジェクトを書き込む。

 Path.write_bytes(data)


以下の例では、ソースコードの同階層にあるtestディレクトリにあるname.txtファイルに対して、
バイナリデータ(ABCDEFG)を書き込みした後、そのバイナリデータを読み込み標準出力に出力している。

 import pathlib
 
 p = pathlib.Path('./test/name.txt')
 p.write_bytes(b'ABCDEFG')
 
 data = p.read_bytes()
 print(data)
 
 p.close()
 
 # 出力
 b'ABCDEFG'


また、1度に読み込むデータのバイト数を指定する場合は、従来の方法と同様、ファイルオブジェクトに対して、readメソッド等を使用する。
詳細は、Pythonの基礎 - ファイル#バイナリファイルを参照すること。