文字エンコーディングの基礎
コンピュータは内部で二進数しか認識できませんが、ユーザーは様々な言語の文字を見ています。文字エンコーディングは、人間の文字と数値の対応関係を記録したデータです。
エンコーディングの歴史
1. ASCIIの独占時代
コンピュータはアメリカで発明され、英語文字を認識するためにASCIIコードが開発されました。ASCIIは英文字と記号を数値にマッピングします。当初は7ビットで、後の拡張のために8ビットが使用されました。
2. 多様な地域コードの登場
中国、日本、韓国など、各国は自国の言語をコンピュータで扱うために独自のエンコーディングを開発しました。
- GBK: 中国語、英語、数字の対応関係を記録します。英語は1バイト、中国語は2バイト以上を使用します。
- Shift_JIS: 日本語、英語、数字の対応関係を記録します。
- Euc_kr: 韓国語、英語、数字の対応関係を記録します。
3. UnicodeとUTF-8の統一
異なる国のテキストデータを無障碍で交換するため、エンコーディングの統一が必要となりました。
- Unicode (万国コード): すべての文字を一貫した数値で表現します。
- UTF-8: Unicodeの最適化版です。ASCII文字は1バイト、その他の文字(例えば中国語)は3バイト以上を使用します。現在、UTF-8がデフォルトで使用されています。
Pythonでのエンコードとデコード
Pythonでは、文字列をエンコードしてバイト列に変換したり、バイト列をデコードして文字列に戻したりできます。
エンコードとデコードの方法
.encode(): 指定されたエンコーディングに基づいて文字列をバイト列に変換します。.decode(): 指定されたエンコーディングに基づいてバイト列を文字列に変換します。
# 文字列をUTF-8でエンコード
original_text = "毎日少しずつ、毎日少しずつ、最終的に学んだことが増えます"
encoded_bytes = original_text.encode('utf-8')
print(encoded_bytes) # b'\xe6\xaf\x8e\xe6\x97\xa5\xe5\xb0\x91\xe3\x81\x97\xe3\x81\x9a\xe3\x81\xa4...'
print(type(encoded_bytes)) # <class 'bytes'>
# バイト列をUTF-8でデコード
decoded_text = encoded_bytes.decode('utf-8')
print(decoded_text) # 毎日少しずつ、毎日少しずつ、最終的に学んだことが増えます
ファイルの文字化け問題の解決
ファイルを開く際は、ファイルが作成された時のエンコーディングと同じエンコーディングを指定する必要があります。
Pythonバージョンによる違い
- Python 2.x: 内部エンコーディングはデフォルトでASCIIです。ファイルの先頭に
# -*- coding: utf-8 -*-を記述し、文字列の前にuを付ける必要があります。 - Python 3.x: 内部エンコーディングはデフォルトでUTF-8です。
ファイル操作の基本
ファイルは、オペレーティングシステムが提供するハードディスクを操作するためのインターフェースです。Pythonでは open() 関数を使用してファイルを操作します。
ファイルのパス
ファイルのパスには相対パスと絶対パスがあります。パス内の特殊文字をエスケープするには、パス文字列の前に r を付けます。
# 絶対パスの例
file_path = r'C:\Users\user\Documents\data.txt'
ファイルの読み書きモード
open() 関数の第二引数でファイルのモードを指定します。
- r (読み込み専用): ファイルを読み込みます。ファイルが存在しない場合はエラーが発生します。
- w (書き込み専用): ファイルを新規作成して書き込みます。ファイルが存在する場合は内容を上書きします。
- a (追記専用): ファイルの末尾にデータを追加します。
with文による安全なファイル操作
with 文(コンテキストマネージャ)を使用すると、ファイル操作が完了した後に自動的にファイルを閉じることができます。
# 読み込みモード (r)
try:
with open('example.txt', 'r', encoding='utf-8') as file_obj:
content = file_obj.read()
print(content)
except FileNotFoundError:
print("ファイルが見つかりません。")
# 書き込みモード (w)
with open('new_file.txt', 'w', encoding='utf-8') as file_obj:
file_obj.write("新しいデータ
")
file_obj.write("もう一つの行
")
# 追記モード (a)
with open('new_file.txt', 'a', encoding='utf-8') as file_obj:
file_obj.write("追記されたデータ
")