【Python】ファイルを開いて閉じる。open関数の使い方【入門第55回】
目次
- Pythonでファイルを開くには?
- ファイルの開き方
- ファイルオブジェクトの受け取り方
- ファイルの閉じ方
- with文を使ったファイルの開閉
- ファイルのモード
- ファイルのエンコーディング
- ファイルと例外
- おわりに
- 関連動画
Pythonでファイルを開くには?
こんにちは、narupoです。
今回はファイル操作の基本、ファイルを開いて閉じる方法を解説します。
ファイルを開けるようになると、ファイルを利用したプログラミングが出来るようになります。
この記事をとっかかりに覚えてみましょう。
具体的には↓を見ていきます。
ファイルの開き方
ファイルオブジェクトの受け取り方
ファイルの閉じ方
with文を使ったファイルの開閉
ファイルのモード
ファイルのエンコーディング
ファイルと例外
ほかのファイル入出力についての入門記事は↓をご覧ください。
- 【Python】ファイルを開いて閉じる。open関数の使い方【入門第54回】
- 【Python】テキストファイルの読み込み(モードr, rt)【入門第55回】
- 【Python】テキストファイルへの書き込み(モードw, wt)【入門第56回】
- 【Python】テキストファイルへの追記(モードa, at)【入門第57回】
- 【Python】テキストファイルを排他的に開いて書き込む(モードx, xt)【入門第58回】
- 【Python】バイナリファイルの読み込み(モードrb)【入門第59回】
- 【Python】バイナリファイルへの書き込み(モードwb)【入門第60回】
- 【Python】バイナリファイルへの追記(モードab)【入門第61回】
- 【Python】バイナリファイルを排他的に開いて書き込む(モードxb)【入門第62回】
- 【Python】テキストファイルを読み書きモードで開く(モードr+, r+t)【入門第63回】
- 【Python】テキストファイルを読み書きモードで新規作成して開く(モードw+, w+t)【入門第64回】
- 【Python】テキストファイルを読み書きモードで、新規作成して、排他的に開く(モードx+, x+t)【入門第65回】
- 【Python】バイナリファイルを読み書きモードで開く(モードr+b)【入門第66回】
- 【Python】バイナリファイルを読み書きモードで新規作成して開く(モードw+b)【入門第67回】
- 【Python】バイナリファイルを読み書きモードで排他的に開く(モードx+b)【入門第68回】
- 【Python】テキストファイルを読み書きモードで追記する(モードa+)【入門第69回】
- 【Python】バイナリファイルを読み書きモードで追記する(モードa+b)【入門第70回】
- 【Python】バイナリファイルのランダムアクセスの基本・前編【入門第71回】
- 【Python】バイナリファイルのランダムアクセスの基本・後編【入門第72回】
- 【Python】ランダムアクセスによる固定長レコードの読み書き・前編【入門第73回】
ファイルの開き方
Pythonでファイルを開くにはopen
関数を使います。
:::text
open(ファイルのパス)
open
関数の第1引数にファイルへのパスを渡すと、open
関数はテキストファイルの読み込みモードでファイルを開きます。
たとえば↓のようなファイルfoods.txt
があるとします。
:::text
チャーハン
青椒肉絲
エビチリ
このファイルfoods.txt
を開くには↓のようにします。
:::python
open('foods.txt')
↑の場合ですが、これはスクリプトと開きたいファイルが同じ階層、つまり同じフォルダ内などにある場合です。
ファイルのパスを絶対パスで指定する場合はWindows環境では↓のようにします。
:::python
open('C:\\path\\to\\foods.txt')
Linux系では↓です。
:::python
open('/path/to/foods.txt')
相対パスでファイルを開きたい場合は↓のようにします。
:::python
open('.\\foods.txt')
open('..\\..\\foods.txt')
Linux系では↓です。
:::python
open('./foods.txt')
open('../../foods.txt')
相対パスの場合は、Pythonインタプリタを実行した階層がパスの基点になります。
スクリプトファイルの位置が基点になるわけではないので間違えないようにしましょう。
ファイルオブジェクトの受け取り方
open
関数はファイルを開くことに成功するとファイルオブジェクトを返します。
ファイルオブジェクトを変数に入れるには↓のようにします。
:::python
fin = open('foods.txt')
変数fin
がファイルオブジェクトです。
ちなみにfin
というのはfile input
の略です。
これと対になるのが書き込みモードのfout
, file output
の略ですね。
さらに読み書きモードではfp
, file pointer
という略もよく使われます。
ここら辺は慣用的な命名なので好きな名前を付けて頂いてもかまいません。
open
関数はデフォルトではテキストファイルの読み込みモードでファイルを開きますが、そのファイルオブジェクトのタイプは、
:::python
fin = open('foods.txt')
print(type(fin))
↓のようになります。
<class '_io.TextIOWrapper'>
このオブジェクトのタイプはファイルを開くモードによって変わることがあります。
ファイルの閉じ方
open
関数でファイルオブジェクトを開くと、そのファイルオブジェクトは開かれた状態です。
ファイルオブジェクトを閉じる、つまりファイルを閉じるにはファイルオブジェクトのメソッドclose
を使います。
:::python
fin = open('foods.txt')
fin.close()
↑のようにするとファイルを閉じることができます。
ファイルを「開いて、閉じる」というのはファイルを扱う時の基本です。
ファイルは開いたら必ず閉じるようにしましょう。
開いたファイルを閉じないと、プログラムでいろいろな不具合が起こることがあります。
ちゃんと閉じていないファイルに再びアクセスすると、ファイルが開きっぱなしなので再度ファイルを開けないなどの不具合や、ほかにもファイルを閉じないばかりに書き込み内容が反映されてなかったりなど、あまりいいことがありません。
なので繰り返しになりますが、ファイルは開いたら必ず閉じるようにしましょう。
with文を使ったファイルの開閉
close
メソッドでファイルを閉じないといけないことはわかりましたが、これがけっこう忘れがちになるのです。
そこでPythonではwith
文というのが用意されています。
with
文を使うと、ファイルオブジェクトのclose
メソッドを呼び出さなくてもファイルを自動的に閉じることができます。
with
文は↓のようにして使います。
:::text
with open(ファイルのパス) as ファイルオブジェクト名:
処理
たとえば↓のようにするとfoods.txt
ファイルを開くことができます。
:::python
with open('foods.txt') as fin:
pass
with
文のブロックが終わると、↑のファイルオブジェクトfin
は自動的にクローズされます。
このようにwith
文を使うとファイルを閉じ忘れるミスが少なくなります。
Pythonでファイルを扱う時はwith
文を使うようにしましょう。
ファイルのモード
冒頭でopen
関数はデフォルトではテキストファイルの読み込みモードでファイルを開くと解説しました。
このモードというのは、ファイルに特徴的なものでたとえば↓のようなモードがあります。
テキストファイルの読み込みモード(r または rt)
テキストファイルの書き込みモード(w または wt)
テキストファイルの追記モード(a または at)
このほかにもまだモードはありますが、今回はテキストファイルに限ったモードを紹介します。
open
関数の引数mode
にモードを指定すると、ファイルを開くときのモードを変更できます。
たとえばテキストファイルの読み込みモードでファイルを開く場合は
:::python
open('foods.txt', mode='r')
open('foods.txt', mode='rt')
などにします。
テキストファイルの書き込みモードでファイルを開くには
:::python
open('foods.txt', mode='w')
open('foods.txt', mode='wt')
で、テキストファイルの追記モードでは
:::python
open('foods.txt', mode='a')
open('foods.txt', mode='at')
です。
ファイルの読み込みモードというのは、ファイルからデータを読み込みたい場合に使います。
つまり、データは読み込むけど書き込みはしないよ、という時に使います。
いっぽうファイルの書き込みモードというのは、ファイルへデータを書き込みたい場合に使います。
これは、データを書き込むけど読み込みはしないよ、という時です。
追記モードと言うのは、ファイルの末尾へデータを追記したい場合に使います。
このほかにも読み書きが両方できる+
モードというものもあります。
ファイルのエンコーディング
パソコンは基本的に0
と1
しか理解できません。
よってファイルも0
と1
で記述されています。
こういったファイルをバイナリーファイルと言います。
バイナリーは2値のことですね。
この0
と1
を合わせてビット(bit)と呼びます。
プログラミングではこのビットの並びをバイト(byte)という単位でよく扱います。
バイトはビットが8
個並んでいるものです(厳密には8
個じゃない場合もあります)。
たとえば↓のようにです。
:::text
00101110
バイト1つを指して1
バイト、バイト2つで2
バイトと表現します。
このバイトがいくつも並んでいるものを指してバイト列(bytes)と言います。
バイナリーファイルはバイトが並んでいるものなので、バイト列の集まりと言うことができます。
このバイナリーファイルをテキストの形式で保存したものをテキストファイルといいます。
つまり、バイトの並びがテキストの形式になっているファイルのことですね。
この「形式」のことをエンコーディングと言います。
たとえば「utf-8
のエンコーディングで保存されたテキストファイル」という風に表現します。
これはファイルのバイトがutf-8
という形式に従って並んでいるということです。
テキストファイルは通常、このエンコーディングを指定して保存されています。
エンコーディングはutf-8
だったりcp932
だったりいろいろありますが、最近のプログラミングではutf-8
を使うのが一般的です。
よってファイルを開くときも、このエンコーディングを指定する必要があります。
このエンコーディングなんですが、open
はデフォルトでは環境依存のエンコーディングでファイルを開こうとします。
Windowsならcp932
、Linux系ならutf-8
が多いはずです。
この環境依存のエンコーディングを確認するには↓のようなコードを書きます。
:::python
import locale
print(locale.getpreferredencoding())
Windows環境では↑のコードの実行結果は↓のようになります。
cp932
エンコーディングを手動で指定したい場合は、open
関数の引数encoding
にエンコーディングを指定します。
:::text
open(ファイルのパス, encoding=エンコーディング)
たとえばfoods.txt
ファイルをutf-8
で開きたい場合は↓のようにします。
:::python
open('foods.txt', encoding='utf-8')
最近のエディターは、デフォルトでutf-8
でテキストファイルを保存する仕様になってることが多いはずです。
しかしWindows環境のデフォルトのエンコーディングはcp932
です。
よって、open
関数にエンコーディングを指定しないと、ファイルを開けないことが多いはずです。
たとえば日本語が含まれているテキストファイルを開こうとするとエラーになるはずです。
utf-8
で保存されているファイルは、↑のようにutf-8
のエンコーディングを指定すると、Windowsでも正しく開けるようになります。
このへんは初心者殺しと言える
エンコーディングがらみのエラーって多いよねー
ファイルと例外
open
関数はファイルを開くことに失敗するとOSError
を継承した例外を送出します。
たとえば↓のように存在しないファイルを開くと、
:::python
open('404')
↓のようにFileNotFoundError
が送出されます。
Traceback (most recent call last):
File ".\sample.py", line 1, in <module>
open('404')
FileNotFoundError: [Errno 2] No such file or directory: '404'
例外の種類については公式で↓のように紹介されています。
FileNotFoundError
はかなりよくお世話になる例外と言えますね。
例外をキャッチするにはtry
文を使います。
:::python
try:
with open('404') as fin:
pass
except FileNotFoundError:
print('ファイルが見つかりませんでした')
おわりに
今回はファイルの入出力処理の前に、ファイルの開閉方法について解説しました。
ファイルの操作は最初はむずかしくて、いや~な感じがすると思います。
しかし慣れてしまえば、なんてことはありません。
なによりファイルの入出力は基本的に設計が統一されているので、一度覚えてしまうとソケット通信や標準入出力の操作などにすぐに応用ができます。
がんばって覚えましょう。
以上、次回に続きます。
また見てね