Python における文字コード

PythonPythonBeginner
オンラインで実践に進む

はじめに

この実験 (Lab) では、Python における文字エンコーディングについて包括的に理解を深めます。まず、ASCII や国別の ANSI エンコーディングのような初期のエンコーディングの制約から、Unicode 標準の開発とその重要性、そして UTF-8 のような様々な実装に至るまで、文字エンコーディングの歴史と基本概念を探求します。Python 環境におけるデフォルトのエンコーディングを確認する方法を学びます。

この基礎の上に、Python で文字エンコーディングを扱うための実践的なテクニックを習得します。これには、ord() および chr() 関数を使用して文字とその整数表現との間で変換する方法、そして encode() および decode() メソッドを習得して文字列とバイトとの間で変換する方法が含まれます。最後に、デコード処理中に発生する可能性のあるエンコーディングエラーを効果的に処理する方法を学び、Python アプリケーションで堅牢で信頼性の高いテキスト処理を保証します。

これは Guided Lab です。学習と実践を支援するためのステップバイステップの指示を提供します。各ステップを完了し、実践的な経験を積むために、指示に注意深く従ってください。過去のデータによると、この 初級 レベルの実験の完了率は 88%です。学習者から 98% の好評価を得ています。

文字エンコーディングの歴史と概念を探る

このステップでは、文字エンコーディングの歴史と基本概念を探求します。コンピューターがテキストをどのように表現するかを理解することは、さまざまなデータ形式や言語を扱う上で不可欠です。

当初、コンピューターはアメリカ合衆国で開発されたため、ASCII エンコーディングが作成されました。ASCII は単一のバイトを使用して文字を表現し、英字、数字、記号を含み、合計 128 文字です。

コンピューターが世界的に普及するにつれて、ASCII は他の言語の文字を表現するには不十分であることが判明しました。これにより、GB2312、GBK、Big5、Shift_JIS のようなさまざまな国別のエンコーディングが開発されました。これらは総称して ANSI エンコーディングと呼ばれることがよくありました。

これらの異なるエンコーディングの限界に対処するために、Unicode 標準が開発されました。Unicode は、すべての言語のすべての文字に一意のバイナリコードを提供することを目指しており、異なるプラットフォームや言語間での一貫したテキスト処理を可能にします。Unicode は文字コードを定義しますが、それらがどのように格納されるかは定義しません。

UCS4、UTF-8、UTF-16、UTF-32 など、Unicode を実装するいくつかのエンコーディングスキームがあります。これらのうち、UTF-8 は ASCII との後方互換性があるため広く使用されています。

Python 3 では、デフォルトのエンコーディングは UTF-8 であり、アクセント付き文字や記号を含むさまざまな言語の文字を直接使用できます。Python 2 のような古いバージョンでは、通常、スクリプトの先頭に ## -*- coding: UTF-8 -*-## coding=utf-8 のようなコメントを使用してエンコーディングを指定する必要がありました。

sys モジュールを使用して、Python 環境のデフォルトエンコーディングを確認できます。

まず、Terminal -> New Terminal をクリックして、WebIDE の統合ターミナルを開きます。

次に、python と入力して Enter キーを押し、Python 対話型インタープリターを開始します。

python

以下のような出力が表示されるはずです。

Python 3.10.x (main, ...)
[GCC ...] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

次に、sys モジュールをインポートして、デフォルトのエンコーディングを確認します。

import sys
sys.getdefaultencoding()

出力にはデフォルトのエンコーディングが表示され、Python 3 では通常 utf-8 です。

>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>>

exit() と入力して Enter キーを押し、Python インタープリターを終了します。

exit()

ord() と chr() を使用して文字と整数を変換する

このステップでは、組み込みの Python 関数 ord()chr() を使用して、文字とその対応する Unicode の整数表現との間で変換する方法を学びます。

Python 3 では、文字列は Unicode を使用して表現されます。ord() 関数は、単一の文字を入力として受け取り、対応する Unicode の 10 進整数値を返します。

これらの関数を試すために、新しい Python ファイルを作成しましょう。WebIDE で、ファイルエクスプローラーの project ディレクトリを右クリックし、New File を選択します。ファイル名を char_conversion.py とします。

char_conversion.py をエディターで開き、次のコードを追加します。

## ord() を使用して文字の Unicode 10 進数値を 取得する
char1 = 'a'
char2 = 'é'
char3 = ';'

print(f"'{char1}' の Unicode 10 進数値は:{ord(char1)}")
print(f"'{char2}' の Unicode 10 進数値は:{ord(char2)}")
print(f"'{char3}' の Unicode 10 進数値は:{ord(char3)}")

ファイルを保存します (Ctrl + S または macOS では Cmd + S)。

次に、統合ターミナルを再度開きます(まだ開いていない場合)。python コマンドを使用してスクリプトを実行します。

python char_conversion.py

以下のような出力が表示されるはずです。

'a' の Unicode 10進数値は: 97
'é' の Unicode 10進数値は: 233
';' の Unicode 10進数値は: 59

chr() 関数は逆の操作を実行します。Unicode コードポイントを表す 10 進整数(または 16 進整数)を受け取り、対応する文字を返します。

chr() 関数を使用するために、char_conversion.py にさらにコードを追加しましょう。既存のコードに次の行を追加します。

## chr() を使用して Unicode 10 進数値から文字を取得する
int1 = 8364
int2 = 8482

print(f"Unicode 10 進数値 {int1} の文字は:{chr(int1)}")
print(f"Unicode 10 進数値 {int2} の文字は:{chr(int2)}")

## chr() で 16 進数値を使用することもできます
hex_int = 0x00A9 ## 文字 '©' の 16 進数
print(f"Unicode 16 進数値 {hex(hex_int)} の文字は:{chr(hex_int)}")

ファイルを再度保存します。

ターミナルからスクリプトを実行します。

python char_conversion.py

出力には chr() 関数の結果が含まれるはずです。

'a' の Unicode 10進数値は: 97
'é' の Unicode 10進数値は: 233
';' の Unicode 10進数値は: 59
Unicode 10進数値 8364 の文字は: €
Unicode 10進数値 8482 の文字は: ™
Unicode 16進数値 0xa9 の文字は: ©

文字の 16 進数 Unicode 表現をどのように見つけるか疑問に思うかもしれません。ord() 関数を使用して 10 進値を取得し、次に組み込みの hex() 関数を使用して 10 進値をその 16 進数文字列表現に変換できます。

char_conversion.py に次のコードを追加します。

## 文字をその 16 進数 Unicode 表現に変換する
char_copyright = '©'
decimal_copyright = ord(char_copyright)
hexadecimal_copyright = hex(decimal_copyright)

print(f"'{char_copyright}' の 16 進数 Unicode 値は:{hexadecimal_copyright}")

ファイルを保存し、最後にもう一度実行します。

python char_conversion.py

最終的な出力には、文字 '©' の 16 進数値が含まれます。

'a' の Unicode 10進数値は: 97
'é' の Unicode 10進数値は: 233
';' の Unicode 10進数値は: 59
Unicode 10進数値 8364 の文字は: €
Unicode 10進数値 8482 の文字は: ™
Unicode 16進数値 0xa9 の文字は: ©
'©' の16進数 Unicode 値は: 0xa9

これにより、ord()chr()、および hex() を組み合わせて Python で文字エンコーディングを扱う方法が示されます。

encode() と decode() を使用して文字列とバイトを変換する

このステップでは、encode() および decode() メソッドを使用して、Python の文字列(Unicode)とバイトオブジェクトの間で変換する方法を学びます。これは、特定のエンコーディング形式で送信または保存する必要があるデータを扱う場合に不可欠です。

encode() メソッドは、指定されたエンコーディングを使用して文字列をバイトオブジェクトに変換するために使用されます。これは bytes オブジェクトを返します。

~/project ディレクトリに encoding_decoding.py という名前の新しい Python ファイルを作成しましょう。

encoding_decoding.py をエディターで開き、次のコードを追加します。

## 文字列を定義する
my_string = 'café'

## 文字列を UTF-8 を使用してエンコードする
encoded_utf8 = my_string.encode('utf-8')

## 文字列を Latin-1 を使用してエンコードする
encoded_latin1 = my_string.encode('latin-1')

## エンコードされたバイトオブジェクトを出力する
print(f"元の文字列:{my_string}")
print(f"UTF-8 でエンコード:{encoded_utf8}")
print(f"Latin-1 でエンコード:{encoded_latin1}")

ファイルを保存します。

次に、統合ターミナルからスクリプトを実行します。

python encoding_decoding.py

元の文字列と、UTF-8 および Latin-1 でのバイト表現を示す出力が表示されるはずです。

元の文字列: café
UTF-8 でエンコード: b'caf\xc3\xa9'
Latin-1 でエンコード: b'caf\xe9'

バイトオブジェクトの出力が b' で始まることに注意してください。これは、それらがバイトリテラルであることを示しています。16 進数は、各エンコーディングでの文字列のバイトシーケンスを表します。

decode() メソッドは、指定されたエンコーディングを使用してバイトオブジェクトを文字列に戻すために使用されます。

作成したバイトオブジェクトをデコードするために、encoding_decoding.py にコードを追加しましょう。既存のコードに次の行を追加します。

## バイトオブジェクトを文字列にデコードする
decoded_utf8 = encoded_utf8.decode('utf-8')
decoded_latin1 = encoded_latin1.decode('latin-1')

## デコードされた文字列を出力する
print(f"UTF-8 からデコード:{decoded_utf8}")
print(f"Latin-1 からデコード:{decoded_latin1}")

ファイルを保存します。

スクリプトを再度実行します。

python encoding_decoding.py

出力には、UTF-8 および Latin-1 バイトから正常にデコードされた元の文字列が表示されます。

元の文字列: café
UTF-8 でエンコード: b'caf\xc3\xa9'
Latin-1 でエンコード: b'caf\xe9'
UTF-8 からデコード: café
Latin-1 からデコード: café

これは、特定のエンコーディングを使用して文字列をバイトにエンコードし、バイトを文字列にデコードする基本的なプロセスを示しています。エラーを回避するためには、エンコードとデコードの両方に正しいエンコーディングを使用することが重要です。これは次のステップで詳しく説明します。

デコード時のエンコーディングエラーの処理

このステップでは、誤ったエンコーディングを使用してバイトをデコードしようとした場合に何が起こるか、およびそのようなエラーを処理する方法を探ります。

前のステップで見たように、バイトを正常にデコードするには、それらのバイトを作成するために使用された元のエンコーディングを知る必要があります。互換性のないエンコーディングでバイトをデコードしようとすると、Python はエラーを発生させます。

これを実証するために、encoding_decoding.py ファイルを変更しましょう。ファイルをエディターで開き、次のコードを末尾に追加します。

## Latin-1 でエンコードされたバイトを ASCII を使用してデコードしようとする
try:
    decoded_incorrectly = encoded_latin1.decode('ascii')
    print(f"Latin-1 を ASCII でデコード:{decoded_incorrectly}")
except UnicodeDecodeError as e:
    print(f"Latin-1 を ASCII でデコード中にエラー: {e}")

ファイルを保存します。

ターミナルからスクリプトを実行します。

python encoding_decoding.py

出力には、Latin-1 バイトを ASCII でデコードしようとしたときのエラーメッセージが含まれるようになります。

元の文字列: café
UTF-8 でエンコード: b'caf\xc3\xa9'
Latin-1 でエンコード: b'caf\xe9'
UTF-8 からデコード: café
Latin-1 からデコード: café
Latin-1 を ASCII でデコード中にエラー: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)

UnicodeDecodeError は、ASCII コーデックが ASCII 標準に従って無効なバイトに遭遇したことを示しています。この場合、バイト 0xe9 は 'é' の Latin-1 表現ですが、有効な ASCII 文字ではありません(ASCII は 0 ~ 127 の文字のみをカバーします)。

デコード時、decode() メソッドの errors パラメータを使用してエラーの処理方法を指定することもできます。一般的なエラー処理戦略には次のものがあります。

  • 'strict' (デフォルト): UnicodeDecodeError を発生させます。
  • 'ignore': デコードできないバイトを無視します。
  • 'replace': デコードできないバイトを置換文字(通常は ``)に置き換えます。
  • 'xmlcharrefreplace': デコードできないバイトを XML 文字参照に置き換えます。

'ignore' および 'replace' エラー処理戦略の使用例を encoding_decoding.py に追加しましょう。次のコードを追加します。

## Latin-1 でエンコードされたバイトを ASCII を使用してエラー処理でデコードしようとする
decoded_ignore = encoded_latin1.decode('ascii', errors='ignore')
decoded_replace = encoded_latin1.decode('ascii', errors='replace')

print(f"Latin-1 を ASCII でデコード (エラー無視): {decoded_ignore}")
print(f"Latin-1 を ASCII でデコード (エラー置換): {decoded_replace}")

ファイルを保存します。

スクリプトを再度実行します。

python encoding_decoding.py

出力には、エラー処理の結果が表示されるようになります。

元の文字列: café
UTF-8 でエンコード: b'caf\xc3\xa9'
Latin-1 でエンコード: b'caf\xe9'
UTF-8 からデコード: café
Latin-1 からデコード: café
Latin-1 を ASCII でデコード中にエラー: 'ascii' codec can't decode byte 0xe9 in position 3: ordinal not in range(128)
Latin-1 を ASCII でデコード (エラー無視): caf
Latin-1 を ASCII でデコード (エラー置換): caf

ご覧のとおり、'ignore' は無効なバイトが無視されて 'é' 文字が削除されたため、"caf" になります。'replace' は無効なバイトを置換文字 `` に置き換えるため、"caf" になります。

適切なエラー処理戦略の選択は、特定のニーズによって異なります。ほとんどの場合、エンコーディングの問題を早期に検出するために、開発中は 'strict' を使用するのが最善です。本番環境では、エンコーディングの問題が発生する可能性のあるデータを処理する必要がある場合に 'replace' または 'ignore' を選択するかもしれませんが、これによりデータが失われたり破損したりする可能性があることに注意してください。

まとめ

この実験では、ASCII とその限界から始まり、さまざまな国別のエンコーディングの開発、そして最終的には Unicode 標準へとつながる、文字エンコーディングの歴史と基本的な概念を探りました。Unicode はすべての文字に一意のコードを提供し、Python 3 のデフォルトであり ASCII と後方互換性のある UTF-8 のようなさまざまなエンコーディングスキームによって実装されていることを学びました。また、sys モジュールを使用して Python のデフォルトエンコーディングを確認する方法も学びました。

次に、ord() および chr() 関数を使用して文字とその整数表現の間で、また encode() および decode() メソッドを使用して文字列とバイトの間で変換する練習をしました。最後に、デコードプロセス中に発生する可能性のあるエンコーディングエラーの処理方法について説明しました。

Morty Proxy This is a proxified and sanitized view of the page, visit original site.