ファイル操作の基本
9.1 ファイル操作の基本
Pythonでは、ファイル操作を行うことができる組み込み関数が用意されております。この組み込み関数を介して、ファイルの読み込みや、書き込みを行うことができます。
ではどのようにファイル操作を行えば良いのでしょうか。Pythonにおけるファイル操作は、ファイルを開くところから始まり、ファイルを閉じるところで終わります。
そのため以下では、①ファイルを開く方法、②ファイルを閉じる方法、③ファイルを読み込む方法、④ファイルを書き出す方法に分けて解説していきます。
9.1.1 ファイルを開くopen()
まずファイル操作を行うために、組み込み関数open()を使用します。この関数は「ファイルを開く」ための関数ですが、オブジェクト化(変数に代入)することで、ファイルの読み書きや、ファイルを閉じるなど、一連のファイル操作を全て行うことができます。
書式
open関数を使ったファイルを開く書式は以下の通りです。
オブジェクト名 = open(‘ファイル名.拡張子名’)
open関数の引数には、ファイル名と共に拡張子もまとめて指定します。また関数を使う際には、変数に代入することでオブジェクト化します。
凡例
#ファイルを読み込む fileData = open('Sample.txt')
9.1.2 ファイルを閉じる closeメソッド
一度、読み込んだファイルは閉じなければなりません。そのためPythonではファイルを開く操作と同時に、ファイルを閉じる操作も指定をします。
ファイルを閉じるためには、open関数によりオブジェクト化した変数(ファイルオブジェクト)のcloseメソッドを使います。
書式
ファイルオブジェクトのcloseメソッドによりファイルを閉じる書式は以下の通りです。
オブジェクト名 = open(‘ファイル名.拡張子名’) ファイル操作の処理内容… オブジェクト名.close()
凡例
#ファイルを読み込む fileData = open('Sample.txt') #ファイルを閉じる fileData.close()
9.1.3 ファイルの読み込み
続いてファイルの読み込み方法について確認しましょう。
ファイルの読み込みは、ファイルオブジェクトを宣言する際に、open関数の引数に「読み込みモード r」を指定する必要があり、また引数に読み込むファイルの文字コードをエンコーディングに指定します。
書式:読み込み専用のファイルオブジェクトの宣言方法
読み込むためのファイルオブジェクトの宣言方法をまとめると以下の通りになります。
凡例
#ファイルを読み込む fileData = open('Sample.txt','r',encoding="utf-8") #ファイルを閉じる fileData.close()
読み込み時の、ファイルオブジェクトの宣言方法について説明しましたが、では実際にファイルを読み込むためにはどうすれば良いのでしょうか。
ファイルの読み込みは先ほどと同様、ファイルオブジェクトを介して行われます。
1. for文で1行ずつ読み込む
ファイルオブジェクトが格納された変数をイテラブルオブジェクトに、for文を介して読み込んだファイルの情報を1行ずつ取り出すことができます。
書式:for文を介してファイルの情報を1行ずつ表示
for 仮変数 in ファイルオブジェクト名: print(仮変数)
凡例
#ファイルを読み込む fileData = open('Sample.txt','r',encoding="utf-8") # 読み込んだテキストファイルを1行ずつ表示 for i in fileData: print(i) #ファイルを閉じる fileData.close()
実行結果
■世界の「こんにちは」 日本語はこんにちは 韓国語はアンニョン ハセヨ 英語はグッド アフタヌーン 中国語はニーハオ ベトナム語はチャオ アウム ハワイ語はアロハ
2. read()メソッド
close()メソッドと同様、ファイルオブジェクトには読み込み用のメソッドが複数用意されております。その内の一つとして、read()メソッドがあります。
readメソッドは、対象のファイルオブジェクトの情報を文字列として取得するためのメソッドです。
書式:read()メソッド
ファイルオブジェクト名.read()
凡例
#ファイルを読み込む fileData = open('Sample.txt','r',encoding="utf-8") # 読み込んだテキストファイルを表示 print(fileData.read()) #ファイルを閉じる fileData.close()
実行結果
■世界の「こんにちは」 日本語はこんにちは 韓国語はアンニョン ハセヨ 英語はグッド アフタヌーン 中国語はニーハオ ベトナム語はチャオ アウム ハワイ語はアロハ
3. readline()
対象のファイルオブジェクトの情報を1行だけ読み込むメソッドとして、readline()があります。readline()は1回しか使用しない場合、最初の行だけが取得できますが、同じファイルオブジェクトに複数回使用すると、2行目、3行目と、次の行を取得することもできます。
書式:readline()メソッド
ファイルオブジェクト名.readline()
凡例
実行結果
■世界の「こんにちは」 日本語はこんにちは
4. readlines()
readlines()メソッドを使うと、対象のファイルオブジェクトの各行の情報をリストとして取得できます。リストとして取得できるので、インデックス番号を介して特定の行の情報を取得することもできれば、for文を介して各行の情報を一つずつ取得することもできます。
書式:readlines()メソッド
ファイルオブジェクト名.readlines()
凡例
#ファイルを読み込む fileData = open('Sample.txt','r',encoding="utf-8") # 読み込んだテキストファイルを全行、リストとして読み込み lines = fileData.readlines() #読み込んだファイルを1行ずつ表示 print(lines) fileData.close()
実行結果
['■世界の「こんにちは」\n', '日本語はこんにちは\n', '韓国語はアンニョン ハセヨ\n', '英語はグッド アフタヌーン\n', '中国語はニーハオ\n', 'ベトナム語はチャオ アウム\n', 'ハワイ語はアロハ']
9.1.4 readlinesメソッドを使ったファイル操作のプログラム
先ほどのreadlinesメソッドを使って、対象のファイルの情報を1行ずつ読み込むプログラムを確認していきましょう。
ソース・フォルダー: /Desktop/Python基礎講座
ファイル名: 第9章.ipynb
アクセスURL: http://localhost:8888/notebooks/Desktop/Python基礎講座/第9章.ipynb
#ファイルを読み込む fileData = open('Sample2.txt','r',encoding="utf-8") # 読み込んだテキストファイルを全行、リストとして読み込み lines = fileData.readlines() #読み込んだファイルを1行ずつ表示 for line in lines: print(line) fileData.close()
実行結果
佐藤 田中 鈴木 山田
解説
1、2行目で、open関数を介してファイル操作をするために必要なファイルオブジェクトを生成してます。
#ファイルを読み込む fileData = open('Sample2.txt','r',encoding="utf-8")
引数にはファイル名「’Sample2.txt’」を指定してますが、このプログラムの様にファイル名のみを指定すると、このプログラムを実行しているファイルと同じ階層のファイルを参照します。
「読み込みモード r」にencoding引数には「utf-8」を指定しています。
2行目の処理を行うことでファイルオブジェクト(インスタンス)の変数のfileDataが、ファイル実体の場所情報を指し示すようになります。
図 9.1 1: ファイル取り込み
5行目で、ファイルオブジェクトfileDataのreadlines()メソッドを使って、「Sample.txt」の各行のデータをリストとして取得し、その戻り値を変数linesに格納してます。
lines = fileData.readlines()
8、9行目でlinesをイテラブルオブジェクトとして、仮変数をlineにlinesの各データを出力しております。
for line in lines: print(line)
引数にはファイル名「’Sample2.txt’」を指定してますが、このプログラムの様にファイル名のみを指定すると、このプログラムを実行しているファイルと同じ階層のファイルを参照します。
8、9行目のイメージを図にまとめると以下の通りになります。
図 9.1 2: for文のデータ取り出し
9.1.5 readlineとwhile文を応用したファイル操作のプロジェクト
readlines()メソッドと違い、readline()メソッドは1行のデータだけを取得するメソッドでしたが、同じファイルオブジェクトに対してreadline()メソッドを複数回、使用すると、最初の行だけでなく、2行目以降も1行ずつ取得することができます。
readline()メソッドの特性と、while文を併用することで、先ほどの「9.1.5:readlineとwhile文を応用したファイル操作のプロジェクト」のfor文とreadlines()メソッドを使ったプログラムと同様の結果が取得できます。
以下でwhile文とreadline()メソッドを使った、プログラムを確認していきましょう。
ソース・フォルダー: /Desktop/Python基礎講座
ファイル名: 第9章.ipynb
アクセスURL: http://localhost:8888/notebooks/Desktop/Python基礎講座/第9章.ipynb
#ファイルを読み込む fileData = open('Sample2.txt','r',encoding="utf-8") # 読み込んだテキストファイルを1行読み込む line = fileData.readline() while line: print(line) # 読み込んだテキストファイルの次の行を読み込む line = fileData.readline() fileData.close()
実行結果
佐藤 田中 鈴木 山田
解説
先ほどと同様、1、2行目で、open関数を介してファイル操作をするために必要なファイルオブジェクトを生成しており、引数にはファイル名「’Sample2.txt’」を指定してます。
#ファイルを読み込む fileData = open('Sample2.txt','r',encoding="utf-8")
5行目で、ファイルオブジェクトfileDataを介して、「Sample2.txt」から最初の1行目のデータを変数lineに格納してます。
line = fileData.readline()
図 9.1 3:readlineメソッドの使用
while line: print(line) # 読み込んだテキストファイルの次の行を読み込む line = fileData.readline()
8行目で、print(line)となっているため、1回目のループでは変数lineには「佐藤」が格納されているので、「佐藤」が出力されます。
ところが10行目で、再び「line = fileData.readline()」とreadline()メソッドを使用しているため、Sample2.txtの次の行のデータが読み込まれ、新しく変数lineに値が格納されます。
Sample2.txtには2行目の情報も存在し、変数lineの値が有効である(true)ため、while文の2回目のループが実行され、今度はSample2.txt 2行目の情報(田中)がlineに格納されている値として出力され、再び「line = fileData.readline()」が実行されるため、今度はSample2.txtの次の3行目のデータが読み込まれ、新しく変数lineに値が格納されます。
このファイルには全部で5行しか存在しないため、4回目のループが繰り替えされると、Sample2.txt の6行目は参照できず、変数lineの値が無効である(false)ため、while文は終了します。
当プログラムのwhile文のイメージを図にまとめると以下の通りです。
図 9.1 4: 繰り返し処理を利用して全データの読み出
最後に12行目で一連のファイル操作の流れを閉じるため、クローズ処理を行ってます。
使用したストリームのクローズ処理を行っています。
fileData.close()
9.1.6 ファイルの書き込み
続いてファイルの書き込み方法について確認していきましょう。ファイルの書き込みは、ファイルオブジェクトを宣言する際に、open関数の引数にファイル名と「書き込みモード w」を指定します。
対象のファイルがなければ新規作成されますが、存在している場合には、元のファイルの中身から新しく書き込む内容に上書きされます。
書式:書き込み専用のファイルオブジェクトの宣言方法
書き込みファイルオブジェクトの宣言方法をまとめると以下の通りになります。
凡例
#書き込み用ファイルオブジェクトの宣言 writeFile = open('writing.txt','w')
では実際にファイルの書き込みを行うためには、どうすれば良いのでしょうか?
2. 文字列としての書き込み
まず文字列として書き込む際には、ファイルオブジェクトのwrite()メソッドを使用します。
書式
ファイルオブジェクト名.write()
凡例
実行結果
Python
9.1.7 テキストファイルへデータを書き出すプログラム
テキストファイルへ文字列を書き出す処理を行います。ファイル出力の方法、および、作成されたファイルのEclipse上での確認方法について学習しましょう。
ソース・フォルダー: /Desktop/Python基礎講座
ファイル名: 第9章.ipynb
アクセスURL: http://localhost:8888/notebooks/Desktop/Python基礎講座/第9章.ipynb
#読み込み用ファイルオブジェクトの宣言 readFile = open('writing2.txt','r',encoding="utf-8") print(readFile.readline()) #読み込み用ファイルのクローズ readFile.close() #書き込み用ファイルオブジェクトの宣言 writeFile = open('writing2.txt','w') sample = 'Python' #ファイルの書き込み writeFile.write(sample) #書き込み用ファイルのクローズ writeFile.close() #読み込み用ファイルオブジェクトの宣言 readFile2 = open('writing2.txt','r',encoding="utf-8") print(readFile2.readline()) #読み込み用ファイルのクローズ readFile2.close()
実行結果
Java Python
解説
1、2行目で、open関数を介して読み込み用のファイルオブジェクトを生成しており、引数にはファイル名「’Writing2.txt’」を指定してます。
#読み込み用ファイルオブジェクトの宣言 readFile = open('writing2.txt','r',encoding="utf-8") print(readFile.readline())
3行目で、readline()メソッドを介して、「writing2.txt」の中身の「Java」が出力されております。
続いて9行目で今度は、書き込み用のファイルオブジェクトを生成しており、先ほどと同じく引数にはファイル名「’Writing2.txt’」を指定してます。
14行目で「Python」という文字列が格納された変数sampleを引数に、こちらのファイルオブジェクトのwrite()メソッドを使用しており、17行目でこちらのファイルオブジェクトをクローズしてます。
#書き込み用ファイルオブジェクトの宣言 writeFile = open('writing2.txt','w') sample = 'Python' #ファイルの書き込み writeFile.write(sample) #書き込み用ファイルのクローズ writeFile.close()
今度はまた新たに読み込み用のファイルオブジェクトを宣言し、同じく引数にはファイル名「’Writing2.txt’」を指定してます。
readline()メソッドを介して「writing2.txt」の中身を取得しておりますが、今度は書き込み用オブジェクトを介して内容が上書きされているため、「Python」が出力されております。
ポイント
- ファイルの書き込みにはファイルオブジェクトの宣言時に「wモード」を指定し、write()メソッドを使用する
9.1.8 ファイル操作におけるその他のモード
open関数に指定できるモードは、読み込みのrや書き込みのwだけではありません。追記モードのaや、読み書きモードのr+やw+などがあります。
以下で読み込み、書き込み以外でよく使用される、モードについて説明します。
1. 追記モード:a
こちらは既存のファイルに新しく内容を付け足したい場合に使用します。
書式
オブジェクト名 = open(‘ファイル名.拡張子名’ ,'a')
書き込みモードと同じく、write()メソッドが使用できます。
凡例
#書き込み用ファイルオブジェクトの宣言 writeFile = open('writing.txt','a',encoding='cp932') writeFile.write('\n'+'Java') #書き込み用ファイルのクローズ writeFile.close() #読み込み用ファイルオブジェクトの宣言 readFile = open('writing.txt','r',encoding='cp932') for line in readFile: print(line) #読み込み用ファイルのクローズ readFile.close()
実行結果
Python Java
先ほど作成した「writing.txt」に「Java」が追記されたのがわかります。また「Java」の前に「\n」が指定されてますが、「\n」は改行を意味します。
2. 読み書きモードのr+
r+は既存のファイルの読み書きをするためのモードです。
書式
読み込み用のメソッド(readline()やreadlines())、書き込み用のメソッド(write())が使用できるので、わざわざ二つのファイルオブジェクトを宣言する必要がなくなるように思えますが、実際に新しく書き込んだ内容を読む込むためには、新たにファイルオブジェクトを生成して読み込み直す必要があります。
凡例
#読み書き用のファイルオブジェクトの宣言 readWrite = open('writing.txt','r+',encoding='cp932') readWrite.write('\n SQL') print('【r+モードでの読み込み】') for line in readWrite: print(line) #読み書き用ファイルのクローズ readWrite.close() #読み込み用ファイルオブジェクトの宣言 readFile = open('writing.txt','r',encoding='cp932') print('【rモードでの読み込み】') for line in readFile: print(line) #読み込み用ファイルのクローズ readFile.close()
実行結果
【r+モードでの読み込み】 Python Java 【rモードでの読み込み】 Python Java SQL
上記の凡例では、r+モードにおけるファイルオブジェクトreadWriteにおいて、write()メソッドで「SQL」という文字列を、「writing.txt」に追記してますが、再びreadWriteを介して、ファイルの中身を1行ずつ読み込んでも、「SQL」は出力されません。
これはファイルの中身は書き換えられたが、ファイルを読み込んだ時点(readWriteにファイルの情報が格納された時点)では、SQLの情報が入っていなかったためであり、「writing.txt」自体には、「SQL」が含まれますが、ファイルオブジェクトreadWriteの中には、その情報は含まれません。
図 9.1 5: r+モードの注意点
そのため読み書き用のファイルオブジェクトreadWriteをクローズした後、新たに読み込み用ファイルオブジェクトreadFileを宣言し、readFileを介してファイルの中身を読み込むと、SQLも含まれております。
1. 読み書きモードのw+
w+モードはr+モードと同じ使い方ができますが、既存ファイルだけでなく新規ファイルの作成にも適用してます。
書式
オブジェクト名 = open(‘ファイル名.拡張子名’ ,'w+')
読み込み用のメソッド(readline()やreadlines())、書き込み用のメソッド(write())が使用できるので、わざわざ二つのファイルオブジェクトを宣言する必要がなくなるように思えますが、r+モードと同様、実際に新しく書き込んだ内容を読む込むためには、新たにファイルオブジェクトを生成して読み込み直す必要があります。
凡例
#読み書き用のファイルオブジェクトの宣言 readWrite = open('writing3.txt','w+',encoding='cp932') readWrite.write('Hello World') print('【r+モードでの読み込み】') for line in readWrite: print(line) #読み書き用ファイルのクローズ readWrite.close() #読み込み用ファイルオブジェクトの宣言 readFile = open('writing3.txt','r',encoding='cp932') print('【rモードでの読み込み】') for line in readFile: print(line) #読み込み用ファイルのクローズ readFile.close()
実行結果
【r+モードでの読み込み】 【rモードでの読み込み】 Hello World
上記の凡例では、w+モードにおけるファイルオブジェクトreadWriteにおいて、write()メソッドで「Hello World」という文字列を、新規ファイル「writing3.txt」に書き込みをしてますが、再びreadWriteを介して、ファイルの中身を1行ずつ読み込んでも、情報は出力されません。
先ほどと同様、ファイルを読み込んだ時点(readWriteにファイルの情報が格納された時点)では、書き込んだ情報が入っておらず、「writing3.txt」自体には、「Hello World」が含まれますが、ファイルオブジェクトreadWriteの中には、その情報は含まれません。
9.1.9 テキストファイルへ繰り返し処理を利用し配列データを書き出すプログラム
テキストファイルへ繰り返し処理を利用して、配列データの文字列を書き出す処理を行います。繰り返し処理と配列を利用した効率の良いファイル出力のロジックについて学習しましょう。
ソース・フォルダー: /Desktop/Python基礎講座
ファイル名: 第9章.ipynb
アクセスURL: http://localhost:8888/notebooks/Desktop/Python基礎講座/第9章.ipynb
#書き込み用ファイルオブジェクトの宣言 writeFile = open('writing4.txt','a',encoding='cp932') names = ['佐藤','田中','鈴木','山田'] #ファイルの書き込み for name in names: writeFile.write(name +'\n') #書き込み用ファイルのクローズ writeFile.close() #読み込み用ファイルオブジェクトの宣言 readFile = open('writing4.txt','r',encoding='cp932') for line in readFile: print(line) #読み込み用ファイルのクローズ readFile.close()
実行結果
佐藤 田中 鈴木 山田
解説
2行目で追記モードaのファイルオブジェクトwriteFileを生成し、対象のファイルを「writing3.txt」に指定しております。
書き込み用データを文字列配列に用意しています。
writeFile = open('writing4.txt','a',encoding='cp932')
続いて4行目で書き込み用データを文字列配列に用意しています。
names = ['佐藤','田中','鈴木','山田']
7、8行目でfor文を介してnamesから1つずつ要素を取り出し、write()メソッドで「writing3.txt」に値を書き込みます。
for name in names: writeFile.write(name +'\n')
11行目でwriteFileはクローズします。
writeFile.close()
そして14行目で読み込み用のファイルオブジェクトreadFileを宣言し、16、17行目で「writing3.txt」の各行のデータを出力します。
readFile = open('writing4.txt','r',encoding='cp932') for line in readFile: print(line)
出力が終わったらreadFileのクローズをします。
readFile.close()
繰り返し処理を利用して配列データを書き込む手法はそれほど難しくなかったはずです。
これまで繰り返し処理と連携して配列データの出力表示することは行ってきました。今回のプログラムではデータの出力先が書き込みファイルになっているだけの違いでしかありません。
クローズ処理
ファイル操作でクローズ処理を忘れてしまうとファイル操作は行えますが、ファイルのデータが保存されないのなどの事態を招くので、必ず処理を行わないといけません。そのためファイルオブジェクトを宣言する際には、close()メソッドを指定し忘れないように気を付けましょう。