【初心者向け】Pythonでtxtファイルを読み込む方法

はい、承知いたしました。Pythonでtxtファイルを読み込む方法に関する初心者向けの詳細な記事を、約5000語で記述し、ここに直接表示します。


【初心者向け】Pythonでtxtファイルを読み込む方法を徹底解説

Pythonを使ったプログラミングの世界へようこそ!

Pythonの学習を進める上で、避けて通れない重要なトピックの一つが「ファイル操作」です。特に、最も身近なファイル形式である「テキストファイル(.txtファイル)」の読み込みは、多くのプログラミングタスクの基本となります。

この記事は、Python初心者の方を対象に、テキストファイルを読み込むための様々な方法を、基礎から応用、さらにはエラー対処法まで、徹底的に分かりやすく解説します。約5000語というボリュームで、一つ一つのステップ、そして「なぜそうするのか」という理由まで、じっくりと掘り下げていきます。

この記事を読み終える頃には、自信を持ってPythonでテキストファイルを扱えるようになっているでしょう。さあ、一緒に学んでいきましょう!

1. はじめに:なぜファイル操作が必要なのか?

プログラミングは、データを使って何か処理を行うことがほとんどです。そのデータは、プログラム内で直接記述することもあれば、インターネットから取得することもありますが、多くの場合は「ファイル」としてコンピュータのストレージに保存されています。

たとえば、以下のような様々な場面でファイルの読み込みが必要になります。

  • データ分析: CSVやtxtファイルに保存された顧客データ、売上データなどを読み込んで分析する。
  • ログ処理: サーバーやアプリケーションが生成したログファイル(テキスト形式が多い)を読み込んで、エラーやアクセス状況を監視・分析する。
  • 設定ファイルの読み込み: プログラムの動作を設定するテキスト形式のファイル(ini, conf, yamlなど)を読み込む。
  • 文章処理: 小説やレポートなどのテキストファイルを読み込み、特定の単語をカウントしたり、内容を解析したりする。
  • 既存のデータを利用: 以前保存した計算結果や、他の人が作成したテキストデータをプログラムで利用する。

このように、ファイルからのデータの読み込みは、現実世界の様々な課題をPythonで解決するための、まさに「入り口」となるスキルなのです。

最初は難しく感じるかもしれませんが、Pythonはファイル操作を非常に直感的かつ強力に行えるように設計されています。この記事で丁寧に解説していきますので、安心してください。

2. ファイルとは? テキストファイルとは?

まずは、コンピュータにおける「ファイル」というものがどういうものか、そして特に「テキストファイル」に焦点を当てて理解を深めましょう。

ファイルとは:

コンピュータの世界において、「ファイル」とは、関連する情報をひとまとまりにしてストレージ(ハードディスク、SSDなど)に保存したものです。ファイルには名前(ファイル名)が付けられ、フォルダ(ディレクトリ)に整理して保管されます。

ファイルには様々な種類があります。

  • 実行ファイル: プログラムそのもの(例: .exe, .py など)。コンピュータが直接実行できる形式で書かれています。
  • データファイル: プログラムが利用するためのデータが格納されています。
    • テキストファイル: 人間が読むことのできる文字情報がそのまま記録されたファイル(例: .txt, .log, .csv, .html, .py など)。
    • バイナリファイル: 人間が直接読んでも意味をなさない、コンピュータが処理しやすい形式でデータが記録されたファイル(例: .jpg, .png (画像), .mp3, .wav (音声), .docx, .xlsx (Office文書), .zip (圧縮ファイル) など)。

テキストファイルとは:

私たちがこれから扱うのは「テキストファイル」です。テキストファイルは、基本的にキーボードから入力できる文字(アルファベット、数字、記号、日本語など)と、改行のような制御文字だけで構成されています。

テキストファイルの特徴は以下の通りです。

  • 人間が読める: メモ帳やテキストエディタなどのツールで開けば、内容をそのまま読むことができます。
  • 汎用性が高い: ほとんどのオペレーティングシステムやアプリケーションで互換性があります。
  • 構造はシンプル: 基本的に行の集まりで構成されます。特定の構造を持たせることもありますが(例: CSVのカンマ区切り)、基本的な記録形式はプレーンなテキストです。

Pythonでテキストファイルを読み込むということは、この「人間が読める文字情報の並び」をプログラム内に取り込み、操作することを意味します。

Pythonにおけるファイルオブジェクト:

Pythonでは、ファイルを開くと「ファイルオブジェクト」というものが生成されます。このファイルオブジェクトは、開いたファイルとプログラムを結びつける「橋渡し」のような役割を果たします。

ファイルオブジェクトを通じて、ファイルからデータを読み込んだり、ファイルにデータを書き込んだりといった操作を行います。ファイル操作が完了したら、このファイルオブジェクトを閉じる必要があります。これは、コンピュータがそのファイルを他のプログラムが利用できるように解放するため、また、書き込みの場合はデータが完全にファイルに書き込まれることを保証するためです。

3. Pythonでファイルを開くための基本:open()関数

Pythonでファイル操作を行う第一歩は、目的のファイルを開くことです。これには、組み込み関数である open() を使用します。

open() 関数は、以下のような基本的な形で使います。

python
open(ファイルパス, モード, encoding=エンコーディング)

一つずつ詳しく見ていきましょう。

3.1. ファイルパスの指定

open() 関数の最初の引数は、開きたいファイルがどこにあるかを示す「ファイルパス」です。ファイルパスには、以下の二種類があります。

  • 絶対パス: ファイルの場所をコンピュータのルートディレクトリ(最上位のフォルダ)から正確に指定する方法です。
    • Windowsの例: 'C:\\Users\\UserName\\Documents\\my_file.txt'
    • macOS/Linuxの例: '/Users/UserName/Documents/my_file.txt'
  • 相対パス: 現在実行しているPythonスクリプトの場所(カレントディレクトリ)を基準にしてファイルの場所を指定する方法です。
    • スクリプトと同じフォルダにあるファイル: 'my_file.txt'
    • スクリプトと同じフォルダ内の data フォルダにあるファイル: 'data/my_file.txt' (Linux/macOS) または 'data\\my_file.txt' (Windows – バックスラッシュはエスケープが必要なため二つ重ねるか、raw文字列 r'data\my_file.txt' を使うのが一般的ですが、Pythonではスラッシュ / もWindowsで使えるので 'data/my_file.txt' が推奨されます)
    • スクリプトがあるフォルダの一つ上のフォルダにあるファイル: '../my_file.txt'

初心者のうちは、まずPythonスクリプトと同じフォルダに読み込みたいファイルを置いて、相対パスで 'ファイル名.txt' と指定するのが最も簡単です。

3.2. モードの指定

open() 関数の二番目の引数は、「モード」です。これは、ファイルに対してどのような操作を行いたいかを指定します。モードは文字列で指定します。

主なモードは以下の通りです。

  • 'r' : 読み込みモード (read) – ファイルを読み込むために開きます。ファイルが存在しない場合はエラーになります。
  • 'w' : 書き込みモード (write) – ファイルを書き込むために開きます。ファイルが存在する場合は中身が消去されて新しく書き込まれます。ファイルが存在しない場合は新しく作成されます。
  • 'a' : 追記モード (append) – ファイルの末尾にデータを追記するために開きます。ファイルが存在しない場合は新しく作成されます。
  • 'x' : 新規作成モード (exclusive creation) – ファイルを新規作成し、書き込むために開きます。ファイルが既に存在する場合はエラーになります。
  • 't' : テキストモード (text) – テキストファイルとして扱います。これがデフォルトです。エンコーディングを指定できます。
  • 'b' : バイナリモード (binary) – バイナリファイルとして扱います。エンコーディングの指定はできません。画像や音声ファイルなどを扱う際に使用します。
  • '+' : 読み書きモード (update) – 他のモード ('r', 'w', 'a', 'x') と組み合わせて使用し、読み込みと書き込みの両方を可能にします。例: 'r+' (読み書き、ファイルは既存である必要あり), 'w+' (読み書き、ファイルが存在すれば中身を消去), 'a+' (読み書き、ファイルの末尾に追記)

今回の主役は 'r' モード(読み込みモード)です。 ファイルからデータを読み取りたいときに指定します。モードを省略した場合も 'r' モードとして扱われますが、明示的に指定することが推奨されます。

3.3. エンコーディングの指定

テキストファイルを扱う上で、非常に重要になるのが「エンコーディング」です。エンコーディングとは、コンピュータが文字を扱うために、それぞれの文字に割り当てられた番号(コードポイント)を、どのようにバイト列に変換してファイルに保存するか、またはバイト列をどのように文字に戻すか、というルール(符号化方式)のことです。

世界中には様々な文字が存在し、それらを表現するためのエンコーディングもたくさんあります。代表的なものには、以下の種類があります。

  • 'utf-8': 現在、世界的に最も広く使われている標準的なエンコーディングです。日本語を含む多くの言語の文字を扱えます。互換性が高く、特に指定がない場合は 'utf-8' を使うのが最善です。
  • 'cp932' (または 'shift_jis'): 日本語環境でWindowsの古いシステムなどでよく使われていたエンコーディングです。特定の環境で作成された日本語テキストファイルは、このエンコーディングで保存されていることがあります。
  • 'euc-jp': 日本語環境でUnix系システムなどで使われていたエンコーディングです。

もし、ファイルが保存されたときのエンコーディングと、読み込む際に指定するエンコーディングが異なっていると、文字が正しく表示されず、「文字化け」が発生します。

Python 3では、open() 関数で明示的に encoding 引数を指定することが強く推奨されます。特に日本語を含むテキストファイルを扱う場合は必須と言えます。

“`python

UTF-8で保存されたファイルを読み込む場合

file = open(‘my_utf8_file.txt’, ‘r’, encoding=’utf-8′)

Shift_JISで保存されたファイルを読み込む場合

file = open(‘my_shiftjis_file.txt’, ‘r’, encoding=’cp932′)
“`

もしエンコーディングを指定しなかった場合、Pythonは実行環境のデフォルトエンコーディングを使用しようとしますが、これが必ずしもファイルのエンコーディングと一致するとは限らず、文字化けの原因となります。特に理由がなければ、encoding='utf-8' を指定することを習慣にしましょう。

4. 最も基本的な読み込み方法:read() メソッド

open() 関数でファイルを開いてファイルオブジェクトを取得したら、次にファイルから実際にデータを読み込みます。最も基本的な読み込み方法は、ファイルオブジェクトの read() メソッドを使うことです。

read() メソッドは、ファイルの内容をすべて読み込み、一つの大きな文字列として返します。

基本的な使い方の流れは以下のようになります。

  1. open() 関数でファイルを読み込みモード ('r') で開く。
  2. ファイルオブジェクトの read() メソッドを呼び出し、ファイルの内容を文字列として取得する。
  3. ファイルオブジェクトの close() メソッドを呼び出し、ファイルを閉じる。

コード例を見てみましょう。

まず、読み込むためのサンプルテキストファイルを作成します。ファイル名を sample.txt とし、Pythonスクリプトと同じフォルダに以下の内容で保存してください。

txt
これは
サンプル
テキストファイルです。
Pythonで読み込んでみましょう。
漢字やひらがな、カタカナも含まれます。

そして、以下のPythonコードを実行します。

“`python

ファイルを開く

sample.txtがUTF-8で保存されていると仮定します

file_object = open(‘sample.txt’, ‘r’, encoding=’utf-8′)

ファイルの内容をすべて読み込む

file_content = file_object.read()

読み込んだ内容を表示する

print(file_content)

ファイルを閉じる

file_object.close()

print(“— ファイルを閉じました —“)
“`

このコードを実行すると、sample.txt の内容がコンソールに表示されるはずです。

close() メソッドの重要性:

ファイルを開いたら、必ず close() メソッドでファイルを閉じることが非常に重要です。ファイルを閉じないと、以下のような問題が発生する可能性があります。

  • リソースの解放: OSがファイルを「使用中」と認識し、他のプログラムがそのファイルを操作できなくなることがあります。特に書き込み中のファイルが閉じられないと、データが完全に書き込まれず、ファイルが破損する可能性もあります。
  • メモリやシステムリソースの消費: 開いたままのファイルオブジェクトは、メモリなどのシステムリソースを消費し続けます。多数のファイルを開いたままにしておくと、システムが不安定になる原因になることもあります。
  • データの永続化(書き込みの場合): 書き込みモードでファイルを開いた場合、実際にディスクにデータが書き込まれるのは、ファイルが閉じられるか、またはバッファがフラッシュされたときです。閉じ忘れると、書き込んだはずのデータがファイルに保存されない可能性があります(今回は読み込みですが、閉じることが良い習慣です)。

read(size) で一部だけ読み込む方法:

read() メソッドには、引数として読み込むバイト数(テキストモードの場合は文字数ではありません。エンコーディングによります)を指定することもできます。例えば、read(100) とすると、ファイルの先頭から100バイトだけ読み込みます。

“`python
file_object = open(‘sample.txt’, ‘r’, encoding=’utf-8′)

先頭から10文字だけ読み込む(UTF-8の場合、日本語は1文字3バイトなどになるため正確に10文字になるとは限りません)

テキストモードのread()は、sizeを指定すると、その文字数(正確にはエンコーディングされたバイト数)を読み込もうとしますが、

改行やファイルの終端など、区切りが良いところで読み込みが終わる場合もあります。

一般的にはread()は全体を読むか、sizeを指定してストリーム的に少しずつ読む場合に利用します。

partial_content = file_object.read(10) # UTF-8の場合、これは10バイトを読み込みます。

print(partial_content)

file_object.close()
“`

ただし、テキストファイルを扱う上で read(size) を使う機会は、ファイルをストリームとして扱うような特殊なケースを除けばあまり多くありません。ファイル全体を一括で読み込むか、後述する「行ごとに読み込む」方法を使うのが一般的です。

read() メソッドは非常にシンプルで便利ですが、欠点もあります。それは、ファイルの内容をすべて一度にメモリに読み込んでしまうことです。もしファイルが非常に大きい場合(数百MBや数GB)、コンピュータのメモリ容量を圧迫し、プログラムの動作が遅くなったり、最悪の場合はメモリ不足でプログラムがクラッシュしたりする可能性があります。

このような大きなファイルを扱う際には、後述する「行ごとに読み込む」方法や、「ファイルオブジェクトをイテレータとして使う」方法がより適しています。

5. より安全なファイル操作:with open(...) as ...: 構文

先ほど、ファイルを開いたら必ず close() メソッドでファイルを閉じることが重要だと説明しました。しかし、プログラムの実行中にエラーが発生したり、何らかの例外が発生したりした場合、close() メソッドが呼ばれる前にプログラムが終了してしまう可能性があります。これでは、ファイルが適切に閉じられず、リソースリークなどの問題が発生します。

このような「後処理を必ず実行したい」という状況で役立つのが、Pythonの with ステートメントです。ファイル操作においては、with open(...) as ...: という構文を使うことで、ファイルの読み込みが完了したかどうかに関わらず、自動的にファイルが閉じられることが保証されます。

この構文は、以下のようになります。

python
with open('ファイルパス', 'モード', encoding='エンコーディング') as 変数名:
# ファイルオブジェクト(変数名)を使った処理をここに書く
# このブロックを抜けると、ファイルは自動的に閉じられる

as 変数名 の部分で指定した変数に、開かれたファイルオブジェクトが代入されます。with ブロックの中では、この変数を使ってファイル操作を行います。with ブロックの処理が正常に終了した場合でも、途中でエラーが発生した場合でも、with ブロックを抜ける際には必ずファイルの close() メソッドが自動的に呼び出されます。

これは、Pythonの「コンテキストマネージャ」という仕組みによるものです。open() 関数が返すファイルオブジェクトは、このコンテキストマネージャのプロトコルを実装しているため、with ステートメントで安全に扱うことができるのです。

先ほどの read() メソッドを使った例を、with open 構文で書き直してみましょう。

“`python

sample.txtをUTF-8で読み込みモードで開く

withブロックを抜けると自動的にファイルが閉じられる

with open(‘sample.txt’, ‘r’, encoding=’utf-8′) as file_object:
# ファイルの内容をすべて読み込む
file_content = file_object.read()
# withブロックの中ではfile_objectが利用可能

withブロックを抜けた後、file_objectは自動的に閉じられている

ここで再度file_objectにアクセスしようとするとエラーになる

読み込んだ内容を表示する

print(file_content)

print(“— withブロックを抜けました —“)
“`

このコードは、先ほどのコードと同じ結果を出力しますが、file_object.close() を明示的に書く必要がありません。これにより、コードがシンプルになり、エラー発生時でも確実にファイルが閉じられるという安全性も向上します。

したがって、Pythonでファイル操作を行う際は、with open(...) as ...: 構文を使用することが、ほぼ全ての場合において強く推奨されます。 これをファイル操作の基本的な形として覚えておきましょう。

6. 行ごとに読み込む方法:readline()readlines() メソッド

ファイル全体を一度に読み込む read() メソッドは、ファイルサイズが大きい場合に問題となる可能性があることを説明しました。テキストファイルは多くの場合、「行」の集まりとして構成されています。このような構造を持つファイルを扱う際には、「行ごとに」データを読み込む方法が非常に便利です。

Pythonのファイルオブジェクトには、行ごとに読み込むためのメソッドが二つ用意されています。

  1. readline() メソッド: ファイルから一行だけを読み込みます。ファイルポインタは次の行の先頭に進みます。ファイルの末尾に達すると空の文字列 ('') を返します。
  2. readlines() メソッド: ファイルからすべての行を読み込み、それぞれの行を要素とするリストとして返します。各行の文字列には、末尾の改行文字 (\n) が含まれます。

それぞれの使い方を見ていきましょう。

6.1. readline() で一行ずつ読み込む

readline() は、主にループ処理と組み合わせて、ファイルを一行ずつ処理していく場合に便利です。ファイルの先頭から順番に readline() を呼び出すことで、一行ずつデータを取得できます。

“`python

sample.txtをUTF-8で読み込みモードで開く

with open(‘sample.txt’, ‘r’, encoding=’utf-8′) as file_object:
# 最初の行を読み込む
line1 = file_object.readline()
print(“最初の行:”, line1, end=”) # end=” はprintのデフォルト改行を抑制

# 次の行を読み込む
line2 = file_object.readline()
print("次の行:", line2, end='')

# さらに次の行
line3 = file_object.readline()
print("さらに次の行:", line3, end='')

# ファイルの最後まで読み進めるまで繰り返す
print("\n--- ループで全行読み込み ---")
# ファイルポインタを先頭に戻す(または再度openする)
# with open(...)で開いた場合は、withブロック内でreadlingし続けるか、
# 一度閉じて再度開くのがシンプルです。
# ここではデモンストレーションのため、再度with openを開く例を示します。
# 実際には、一度with openで開いたファイルオブジェクトに対してループを行います。

ループ処理で全行を一行ずつ読み込む場合の典型的なコード

print(“\n— ループ処理例 —“)
with open(‘sample.txt’, ‘r’, encoding=’utf-8′) as file_object:
while True:
line = file_object.readline()
if not line: # ファイルの末尾に達するとreadline()は空文字列”を返す
break
# 読み込んだ行を処理する(ここでは表示)
print(“読み込んだ行:”, line, end=”) # lineには改行文字\nが含まれているので、printのデフォルト改行は不要
# withブロックを抜けると自動的に閉じられる
“`

readline() を使ったループ処理では、while True:if not line: を組み合わせて、ファイルの末尾に達するまで読み込みを続けるパターンがよく使われます。

readline() メソッドで読み込んだ文字列には、行末の改行文字 (\n) が含まれていることに注意してください。表示する際に不要であれば、文字列の strip() メソッド(先頭と末尾の空白文字や改行文字を取り除く)などで整形する必要があります。

6.2. readlines() で全行をリストとして読み込む

readlines() メソッドは、read() メソッドが行全体を一つの文字列として読み込むのに対し、行ごとに分割してリストとして読み込みます。

“`python

sample.txtをUTF-8で読み込みモードで開く

with open(‘sample.txt’, ‘r’, encoding=’utf-8′) as file_object:
# 全行をリストとして読み込む
list_of_lines = file_object.readlines()

withブロックを抜けると自動的に閉じられる

読み込んだリストを表示する

print(“読み込んだリスト:”, list_of_lines)

リストの各要素を表示する

print(“\n— リストの各要素を表示 —“)
for line in list_of_lines:
print(line, end=”) # 各要素に改行が含まれているためend=”
“`

このコードを実行すると、以下のようなリストが出力されるでしょう(リストの各要素に行末の \n が含まれています)。

“`
読み込んだリスト: [‘これは\n’, ‘サンプル\n’, ‘テキストファイルです。\n’, ‘Pythonで読み込んでみましょう。\n’, ‘漢字やひらがな、カタカナも含まれます。\n’]

— リストの各要素を表示 —
これは
サンプル
テキストファイルです。
Pythonで読み込んでみましょう。
漢字やひらがな、カタカナも含まれます。
“`

readlines() メソッドも、read() と同様に、ファイルの内容をすべて一度にメモリに読み込みます。 そのため、非常に大きなファイルを扱う場合にはメモリを圧迫する可能性があります。ファイル全体を行リストとして扱いたい場合に便利ですが、ファイルサイズには注意が必要です。

7. ファイルオブジェクトのイテレーション:最もPythonらしい読み込み方法

Pythonでは、ファイルオブジェクト自体が「イテレータ」として機能します。これはつまり、ファイルオブジェクトを for ループに直接渡すことで、ファイルの内容を一行ずつ自動的に読み込んで処理できるということです。

この方法は、Pythonでテキストファイルを読み込む際の最も推奨される、慣用的で効率的な方法です。

“`python

sample.txtをUTF-8で読み込みモードで開く

withブロックを抜けると自動的にファイルが閉じられる

print(“— forループでファイルオブジェクトをイテレーション —“)
with open(‘sample.txt’, ‘r’, encoding=’utf-8′) as file_object:
# file_object自体をforループで回す
for line in file_object:
# 各lineはファイルの1行(末尾に改行文字\nを含む)
print(“読み込んだ行:”, line, end=”) # 行には改行文字が含まれているためend=”
# withブロックを抜けると自動的に閉じられる
“`

このコードは、readline() を使って while ループで一行ずつ読み込む処理とほぼ同じ結果をもたらしますが、コードが非常に簡潔で分かりやすいです。

ファイルオブジェクトのイテレーションの利点:

  • 簡潔さ: readline()while True ループを組み合わせるよりもコードがシンプルになります。
  • メモリ効率: read()readlines() のようにファイル全体を一度にメモリに読み込むのではなく、一行ずつメモリに読み込んで処理します。 これは、巨大なファイルを扱う際に非常に有利です。ファイルサイズに関わらず、メモリ使用量を低く抑えることができます。
  • Pythonらしさ: この方法はPythonの設計思想に合致しており、Pythonコミュニティで広く使われています。

改行文字の処理 (.strip()):

ファイルオブジェクトのイテレーションで読み込んだ各 line には、通常、行末の改行文字 (\n) が含まれています。この改行文字が不要な場合は、文字列の strip() メソッドを使って取り除くことができます。strip() は、文字列の先頭と末尾にある空白文字(スペース、タブ、改行など)を削除します。

“`python
print(“\n— strip()を使って改行文字を取り除く —“)
with open(‘sample.txt’, ‘r’, encoding=’utf-8′) as file_object:
for line in file_object:
# 行末の改行文字を取り除く
cleaned_line = line.strip()
# 空白行はstrip()すると空文字列”になるのでスキップするなどの処理も考えられる
if cleaned_line: # 空白行でない場合のみ表示
print(“整形された行:”, cleaned_line)
else:
print(“(空白行をスキップ)”)

``
この例では、
strip()を使って改行文字を取り除いた後、print()関数で表示しています。print()関数はデフォルトで行末に改行を追加するため、結果として各行が正しく表示されます。また、ファイル内に完全に空の行(改行文字しかない行)がある場合、strip()すると空文字列”` になるため、それを判定してスキップする例も加えています。

まとめると、テキストファイルを一行ずつ処理したい場合は、with open(...) as ...: 構文とファイルオブジェクトのイテレーション (for line in file_object:) を組み合わせるのが、最も一般的で効率的、かつ安全な方法です。

8. 大規模なファイルを効率よく読み込む

ここまでで、以下の3つの基本的な読み込み方法を学びました。

  • file.read(): ファイル全体を一つの文字列として読み込む。
  • file.readlines(): ファイル全体を各行を含むリストとして読み込む。
  • for line in file:: ファイルを一行ずつイテレーションしながら読み込む。

これらの方法のうち、read()readlines() は、ファイルサイズが大きくなるとメモリを大量に消費するという欠点がありました。これに対し、for line in file: というイテレーションによる読み込みは、一度にメモリに保持するのは現在の行だけであるため、ファイルサイズにほとんど依存せずに処理を進めることができます。

例えば、1GBのテキストファイルがあるとします。

  • read()readlines() を使うと、1GBのテキストデータがそのままメモリ上に読み込まれるため、コンピュータに十分なメモリがないと処理が続行できなくなります。
  • for line in file: を使うと、たとえファイルが1GBあっても、Pythonが一行ずつ読み込み、その一行分のデータだけをメモリに載せて処理します。各行の長さは通常、ファイル全体のサイズに比べて非常に小さい(せいぜい数KB程度)ですから、メモリの消費量を低く抑えることができます。

このため、ファイルサイズが大きいかどうか分からない場合や、非常に大きなファイルを扱う可能性がある場合は、迷わず for line in file: によるイテレーションを選択するべきです。

9. エンコーディングの問題と対策をさらに詳しく

エンコーディング(文字コード)は、テキストファイル処理において最も頻繁に遭遇する問題の一つです。特に日本語環境では、UTF-8、Shift_JIS (cp932)、EUC-JPなど、いくつかのエンコーディングが混在していることがあるため、文字化けが発生しやすいです。

なぜエンコーディングの指定が必要なのか?

コンピュータは文字そのものを直接扱っているわけではなく、文字に割り当てられた数値(コードポイント)をバイト列に変換して扱っています。エンコーディングは、この数値とバイト列の間の変換ルールを定めたものです。

例えば、「あ」という文字は、Unicodeという国際的な文字コード体系では U+3042 というコードポイントを持っています。この U+3042 をバイト列に変換するルールがエンコーディングによって異なります。

  • UTF-8: E3 81 82 という3バイト
  • Shift_JIS: 82 A0 という2バイト
  • EUC-JP: A4 A2 という2バイト

もし、Shift_JISで保存されたファイル(「あ」が 82 A0 と記録されている)を、UTF-8として読み込もうとすると、Pythonは 82 A0 というバイト列をUTF-8のルールで解釈しようとします。しかし、82 A0 はUTF-8としては不正なバイト列の組み合わせであることが多く、結果として「ï½」(豆腐のような表示)や、場合によっては UnicodeDecodeError というエラーが発生します。これが文字化けの正体です。

open() 関数で encoding='utf-8' のように正しいエンコーディングを指定することで、Pythonはファイルのバイト列をそのエンコーディングのルールに従って正しく文字に変換し、文字化けを防ぐことができます。

よく遭遇するエンコーディングと指定方法:

  • UTF-8: 'utf-8'
    • 現在最も推奨されるエンコーディングです。新しくテキストファイルを作成する場合や、Webから取得したデータなどはUTF-8であることが多いです。
    • 特に理由がなければ、まず 'utf-8' を試してみましょう。
  • Shift_JIS (CP932): 'cp932' または 'shift_jis'
    • Windows環境で古くから使われている日本語エンコーディングです。Excelで作成してテキスト形式で保存したファイルや、古いシステムで生成されたテキストファイルはShift_JISであることがあります。
    • Shift_JISとCP932はほぼ同じですが、一部の記号などの扱いに違いがあります。通常は 'cp932' を指定すれば問題ありません。
  • EUC-JP: 'euc-jp'
    • Unix/Linux環境で古くから使われていた日本語エンコーディングです。

エンコーディング指定のコード例:

“`python

UTF-8で保存されたファイルを読み込む

try:
with open(‘utf8_file.txt’, ‘r’, encoding=’utf-8′) as f:
content = f.read()
print(“UTF-8ファイルの内容:\n”, content)
except FileNotFoundError:
print(“エラー: utf8_file.txt が見つかりません。”)
except UnicodeDecodeError:
print(“エラー: utf8_file.txt をUTF-8として読み込めませんでした。エンコーディングが間違っている可能性があります。”)

print(“-” * 20)

Shift_JIS (cp932) で保存されたファイルを読み込む

try:
with open(‘shiftjis_file.txt’, ‘r’, encoding=’cp932′) as f:
content = f.read()
print(“Shift_JISファイルの内容:\n”, content)
except FileNotFoundError:
print(“エラー: shiftjis_file.txt が見つかりません。”)
except UnicodeDecodeError:
print(“エラー: shiftjis_file.txt をcp932として読み込めませんでした。エンコーディングが間違っている可能性があります。”)

``
(注意: このコードを実行するには、
utf8_file.txtshiftjis_file.txt` という名前で、それぞれUTF-8とShift_JISで保存されたサンプルファイルが必要です。)

エンコーディングが不明な場合:

読み込みたいファイルがどのエンコーディングで保存されているか分からない場合、いくつかの方法があります。

  1. 推測: ファイルが作成された環境や経緯から推測する(例: Windowsで作成されたならShift_JISかも、WebからダウンロードしたならUTF-8かも)。
  2. 手動で試す: 'utf-8', 'cp932', 'euc-jp' など、可能性のあるエンコーディングを順番に試してみる。UnicodeDecodeError が発生したら、そのエンコーディングではなさそうだと判断できます。
  3. ライブラリを使う: chardet のような外部ライブラリを使うと、ファイルの内容からエンコーディングを自動的に判定できます。ただし、判定の精度は100%ではありません。

初心者の方にとっては、まず 'utf-8' を試してみて、文字化けしたりエラーが出たりした場合に 'cp932' を試す、というのが現実的なステップでしょう。それでもうまくいかない場合は、ファイルの作成者にエンコーディングを確認したり、高度なエンコーディング判定ツールやライブラリの利用を検討したりすることになります。

補足:errors 引数

open() 関数には errors という引数もあり、エンコーディングエラーが発生した場合の挙動を指定できます。デフォルトは 'strict' で、エンコーディングできないバイト列があると UnicodeDecodeError を発生させます。他に 'ignore' (エラー箇所を無視して読み進める)、'replace' (エラー箇所を代替文字(�)に置き換える) などがあります。

“`python

エンコーディングエラーを無視して読み込む

with open(‘mixed_encoding_file.txt’, ‘r’, encoding=’utf-8′, errors=’ignore’) as f:
content = f.read()
print(“エラー無視で読み込んだ内容:\n”, content)

エンコーディングエラー箇所を代替文字に置き換えて読み込む

with open(‘mixed_encoding_file.txt’, ‘r’, encoding=’utf-8′, errors=’replace’) as f:
content = f.read()
print(“代替文字に置き換えて読み込んだ内容:\n”, content)
``errors=’ignore’‘replace’` は、とにかくファイルを最後まで読みたい場合などに便利ですが、データの正確性が失われる可能性があるため、使用には注意が必要です。可能な限り、正しいエンコーディングを指定して読み込むべきです。

10. エラー処理:ファイル操作で起こりうる問題への備え

ファイル操作は、ファイルが存在しない、ファイルにアクセスする権限がない、エンコーディングが間違っているなど、様々な原因でエラーが発生しやすい処理です。安定したプログラムを作るためには、これらのエラーを適切に処理することが重要です。

Pythonでは、エラー処理に try...except ブロックを使用します。

python
try:
# エラーが発生する可能性のあるコード
# ファイルを開く、読み込むなどの処理
except エラー名 as 変数名:
# 指定したエラーが発生した場合に実行されるコード
# エラーメッセージを表示するなど
except 別エラー名:
# 別のエラーが発生した場合の処理
finally:
# エラーの発生有無に関わらず、必ず最後に実行されるコード
# ファイルを閉じる(with openを使っていれば不要)

ファイル操作でよく遭遇するエラーは以下の通りです。

  • FileNotFoundError: 指定したパスにファイルが見つからない場合に発生します。
  • PermissionError: ファイルにアクセスする権限がない場合に発生します(読み取り禁止など)。
  • UnicodeDecodeError: バイト列を文字列にデコードする際に、指定したエンコーディングで正しくデコードできない場合に発生します(最も多い原因はエンコーディングの誤り)。

これらのエラーを try...except ブロックで捕捉することで、プログラムが予期せず終了することを防ぎ、ユーザーに分かりやすいメッセージを表示したり、代替処理を行ったりすることができます。

エラー処理のコード例:

“`python
file_path = ‘non_existent_file.txt’ # 存在しないファイル

file_path = ‘sample.txt’ # 存在するファイルで試すことも可能

try:
# ファイルを読み込みモードで開く (存在しないのでエラーが発生する想定)
print(f”ファイル ‘{file_path}’ を開こうとしています…”)
with open(file_path, ‘r’, encoding=’utf-8′) as file:
content = file.read()
print(“ファイルの内容:”)
print(content)

except FileNotFoundError:
# FileNotFoundError が発生した場合の処理
print(f”エラー: 指定されたファイル ‘{file_path}’ が見つかりませんでした。”)

except PermissionError:
# PermissionError が発生した場合の処理
print(f”エラー: ファイル ‘{file_path}’ にアクセスする権限がありません。”)

except UnicodeDecodeError:
# UnicodeDecodeError が発生した場合の処理
print(f”エラー: ファイル ‘{file_path}’ のエンコーディングが不正、または指定されたエンコーディング(‘utf-8’)でデコードできませんでした。”)

except Exception as e:
# その他の予期しないエラーが発生した場合の処理
print(f”予期しないエラーが発生しました: {e}”)

finally:
# tryブロックまたはexceptブロックの処理が完了した後、必ず実行される
# with openを使っているので、ファイルオブジェクトを明示的に閉じる必要はないが、
# 後処理が必要な場合などに使う。
print(“ファイル処理の試行が終了しました。”)

``
この例では、存在しないファイルを指定しているため、
FileNotFoundError` が捕捉されて、その中の処理が実行されます。ファイル名やパスを正しいものに変更して実行すると、正常に読み込まれるか、あるいは権限エラーやエンコーディングエラーが発生するかもしれません。

複数の except ブロックを記述することで、異なる種類のエラーに対して個別の処理を行うことができます。また、except Exception as e: のように書くと、全ての種類のエラーを捕捉し、エラーオブジェクト e からエラーメッセージなどを取得できます。

ファイル操作においては、少なくとも FileNotFoundErrorUnicodeDecodeError に対してエラー処理を施しておくことで、より堅牢なプログラムになります。

11. 実践的な例:読み込んだデータを少し加工してみよう

ファイルを読み込むだけでなく、読み込んだデータをプログラムで処理・加工することがほとんどです。ここでは、ファイルから読み込んだテキストデータに対して、簡単な処理を行う例をいくつか紹介します。

使用するファイルは、引き続き sample.txt とします。

例1: 各行に行番号を付けて表示する

ファイルを一行ずつ読み込み、それぞれの行の先頭に行番号を追加して表示する例です。ファイルオブジェクトのイテレーションと enumerate() 関数を組み合わせると簡潔に書けます。enumerate() は、イテラブルなオブジェクト(リストや文字列、そしてファイルオブジェクトなど)から要素を取り出す際に、その要素と同時にインデックス(通常は0から始まる番号)も取得できる便利な関数です。

“`python
print(“\n— 例1: 各行に行番号を付けて表示 —“)
file_path = ‘sample.txt’
try:
with open(file_path, ‘r’, encoding=’utf-8′) as f:
# enumerateを使って行番号と行内容を取得
# enumerateはデフォルトで0から始まるので、1から始めるには start=1 を指定
for line_num, line in enumerate(f, start=1):
cleaned_line = line.strip() # 改行文字を取り除く
print(f”{line_num}: {cleaned_line}”)

except FileNotFoundError:
print(f”エラー: ファイル ‘{file_path}’ が見つかりません。”)
except UnicodeDecodeError:
print(f”エラー: ファイル ‘{file_path}’ のエンコーディングが不正です。”)
出力例:
— 例1: 各行に行番号を付けて表示 —
1: これは
2: サンプル
3: テキストファイルです。
4: Pythonで読み込んでみましょう。
5: 漢字やひらがな、カタカナも含まれます。
“`

例2: ファイル内の特定の単語をカウントする

ファイル全体を読み込み、特定の単語が何回出現するかをカウントする例です。ファイル全体を読み込むため、ファイルサイズが大きい場合は注意が必要です。

“`python
print(“\n— 例2: ファイル内の特定の単語をカウント —“)
file_path = ‘sample.txt’
target_word = ‘Python’
word_count = 0

try:
with open(file_path, ‘r’, encoding=’utf-8′) as f:
content = f.read() # ファイル全体を読み込む

# 読み込んだ内容を小文字に変換し、単語に分割する
# 簡単にするため、ここではスペースや改行で分割すると仮定します
# 実際には句読点なども考慮する必要があります
words = content.lower().split() # 小文字化して単語に分割

# 単語リストをループして、対象の単語をカウント
for word in words:
    # strip()を使って単語の前後にある可能性のある句読点などを取り除く
    # より厳密な単語分割は正規表現などを使いますが、ここでは簡単な例としてstripを使用
    cleaned_word = word.strip('.,!?;:()[]{}')
    if cleaned_word == target_word.lower():
        word_count += 1

print(f"ファイル '{file_path}' の中に '{target_word}' は {word_count} 回出現しました。")

except FileNotFoundError:
print(f”エラー: ファイル ‘{file_path}’ が見つかりません。”)
except UnicodeDecodeError:
print(f”エラー: ファイル ‘{file_path}’ のエンコーディングが不正です。”)
``
この例では、まず
read()でファイル全体を読み込み、.lower()で小文字に変換してから.split()` で単語のリストに分割しています。その後、リストをループして対象の単語をカウントしています。より正確な単語分割には、正規表現や自然言語処理ライブラリを使うこともありますが、ここでは基本的なファイル読み込みの応用として簡単な方法を紹介しました。

例3: CSVライクなファイルを読み込み、データを分割する

カンマ区切りなどの形式でデータが記述されたファイルを読み込み、行と列に分割して扱う例です。CSVファイル(Comma Separated Values)はテキストファイルの一種であり、PythonにはCSVファイルを扱うための標準ライブラリ csv がありますが、ここでは簡単なテキストファイルとして読み込み、文字列操作で分割してみましょう。

以下の内容で data.csv という名前のファイルを作成し、Pythonスクリプトと同じフォルダに保存してください。

csv
名前,年齢,都市
山田太郎,30,東京
佐藤花子,25,大阪
田中一郎,40,福岡

“`python
print(“\n— 例3: CSVライクなファイルを読み込み、データを分割 —“)
file_path = ‘data.csv’

try:
with open(file_path, ‘r’, encoding=’utf-8′) as f:
header = None # ヘッダー行を保存するための変数
data_rows = [] # データ行を保存するためのリスト

    # ファイルを一行ずつ読み込む (forループが効率的)
    for line in f:
        cleaned_line = line.strip() # 行末の改行文字を取り除く
        if not cleaned_line: # 空白行はスキップ
            continue

        # カンマで分割してリストにする
        columns = cleaned_line.split(',')

        if header is None:
            # 最初の行をヘッダーとして保存
            header = columns
        else:
            # 2行目以降をデータ行として保存
            data_rows.append(columns)

# ヘッダーとデータ行を表示
print("ヘッダー:", header)
print("データ行:")
for row in data_rows:
    print(row)

except FileNotFoundError:
print(f”エラー: ファイル ‘{file_path}’ が見つかりません。”)
except UnicodeDecodeError:
print(f”エラー: ファイル ‘{file_path}’ のエンコーディングが不正です。”)
except Exception as e:
print(f”処理中にエラーが発生しました: {e}”)

``
この例では、ファイルを一行ずつ読み込み、各行をカンマ (
,`) で分割しています。最初の行をヘッダーとして扱い、それ以降の行をデータ行としてリストに格納しています。

より複雑なCSVファイルを扱う場合(例: フィールド内にカンマが含まれる場合、クォートされている場合など)は、標準ライブラリの csv モジュールを使うべきです。しかし、簡単なカンマ区切りファイルであれば、このように基本的なファイル読み込みと文字列分割 (.split(',')) で十分に対応できます。

これらの実践例を通じて、ファイルを読み込むだけでなく、読み込んだデータを加工・処理するための基本的なパターンを理解できたかと思います。

12. まとめと次のステップ

この記事では、Pythonでテキストファイル (.txt ファイル) を読み込む方法について、初心者向けに詳細に解説しました。

学んだ主な内容は以下の通りです。

  • ファイル操作の基本と open() 関数の使い方(ファイルパス、モード、エンコーディング)
  • 読み込みモード 'r' の詳細とエンコーディングの重要性('utf-8', 'cp932' など)
  • read() メソッドによるファイル全体の一括読み込み
  • with open(...) as ...: 構文による安全なファイル操作(自動クローズ)
  • readline() メソッドによる一行ずつの読み込み
  • readlines() メソッドによる全行のリスト読み込み
  • ファイルオブジェクトのイテレーション (for line in file:) による効率的な一行ずつの読み込み(最も推奨される方法)
  • 大規模ファイルを扱う際のイテレーションの優位性
  • 文字化けを防ぐためのエンコーディング指定の重要性と対策
  • try...except ブロックによるエラー処理 (FileNotFoundError, UnicodeDecodeError など)
  • 読み込んだデータを加工する簡単な実践例(行番号追加、単語カウント、データ分割)

これで、あなたはPythonでテキストファイルを読み込み、その内容をプログラムで利用する基本的なスキルを習得しました。

次のステップとして、以下のトピックに挑戦してみることをお勧めします。

  • ファイルへの書き込み: 今回は読み込みだけでしたが、テキストファイルにデータを書き込む ('w' モードや 'a' モード) 方法を学ぶと、プログラムの出力結果をファイルに保存できるようになります。
  • 他のファイル形式: CSVファイル (csv モジュール)、JSONファイル (json モジュール)、XMLファイルなど、Pythonには様々なファイル形式を扱うための標準ライブラリや外部ライブラリがあります。
  • より高度なテキスト処理: 正規表現 (re モジュール) を使うと、テキストの中から特定のパターンに一致する文字列を検索したり、抽出したりすることができます。
  • 大規模データ処理: 非常に大きなデータファイル(GB単位など)を効率的に扱うためには、ファイルを行ごとに処理するテクニック(今回学んだイテレーションやジェネレータの活用)が重要になります。また、pandas のようなデータ分析ライブラリは、構造化されたテキストデータ(CSVなど)を非常に効率よく扱うことができます。

ファイル操作は、データサイエンス、Web開発、システム管理など、Pythonの様々な分野で必要となる普遍的なスキルです。今回学んだ基礎をしっかりと身につけて、さらに応用的な学習に進んでください。

もし途中で分からないことがあれば、この記事を読み返したり、公式ドキュメントを参照したり、オンラインで質問したりしてみてください。

あなたのPython学習の旅が素晴らしいものであることを願っています!


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール