Python 文字エンコーディングの詳細な紹介

高洛峰
リリース: 2017-03-28 17:19:58
オリジナル
1447 人が閲覧しました

1. 文字エンコーディングはじめに

1.1. ASCII

ASCII (情報交換用の米国標準コード)、これはシングルバイトエンコーディングであり、コンピューターの世界では当初は英語のみであり、1 バイトで 256 の異なる文字を表すことができ、すべての英語文字と多くの制御記号を表すことができますが、ASCII はそのうちの半分しか使用しません ( x80 以下)、これは MBCS

1.2 の実装の基礎でもあります。しかし、すぐにコンピューターの世界に他の言語が登場し、シングルバイト ASCII はニーズを満たすことができなくなりました。その後、各言語は独自のエンコーディングを開発しました。これは、1 バイトで表現できる文字が少なすぎることと、ASCII エンコーディングとの互換性も必要であるためです。そのため、これらのエンコーディングでは文字を表現するためにマルチバイトが使用されます。 GBxxx、BIGxxx など。その規則は、最初のバイトが x80 より小さい場合は、引き続き ASCII 文字を表し、x80 より大きい場合は、次のバイト (合計 2 バイト) と一緒に文字を表します。

ここで、IBM はこれらのコードを収集し、ページ番号を割り当てるコード ページを発明しました。したがって、CP936 を使用して表すこともできます。 GBCS (マルチ)。バイト文字

セット

) は、これまで誰もが 2 バイトを使用してきたため、DBCS (Double-Byte Character Set) と呼ばれることもあります。 Windows では、MBCS は設定した地域に応じて異なるエンコーディングを参照します。ただし、Windows では、MBCS という文字は表示されません。よりファッショナブルに言うと、Microsoft ANSI は人々を怖がらせるために使用されました。同時に、簡体字中国語 Windows のデフォルトのロケール設定では、GBK を参照するようになりました。人々は、複数のエンコードによって世界が複雑になりすぎて頭が痛くなるのではないかと考え始めました。そこで、全員が集まってブレインストーミングを行い、すべての言語の文字を同じ文字で表現するという方法を考え出しました。

文字セット

. これはオリジナルの Unicode です

。Unicode 標準 UCS-2 は 1 つの文字を表すのに 2 バイトを使用するため、Unicode は 1 つの文字を表すのに 2 バイトを使用するとよく聞きます。 256*256 では小さすぎ、それでも十分ではありませんでした。文字を表すのに 4 バイトを使用する UCS-4 標準が登場しましたが、私たちが最もよく使用しているのは依然として UCS-2 です。 UCS (Unicode Character Set) は、文字に対応するコード ポイントのテーブルです。たとえば、「汉」という単語のコード ポイントは 6C49 です。 UTF (UCS Transformation Format) は、文字の特定の送信と保存を担当します。

これは最初は非常に簡単で、UCS コード ポイント (UTF-16) を使用して保存するだけです。たとえば、「Han」は x6Cx49 を直接使用して (UTF-16-BE) 保存します。 x49x6C を使用して保存します (UTF -16-LE)。しかし、アメリカ人は使ってみて大きな損をしたと感じています。昔は英語の文字を保存するのに1バイトしか必要なかったのに、今では大鍋のご飯を食べると2バイトになり、スペースの消費が2倍になりました。それで、どこからともなくUTF-8になりました。

UTF-8 は非常に扱いにくいエンコーディングであり、可変長であり、ASCII 文字は 1 バイトで表現されます。ただし、ここで省略されたものは他の場所から抽出する必要があります。UTF-8 の漢字は保存に 3 バイトを使用するという話を聞いたことがありますよね。 4 バイトで保存された文字はさらに涙です... (UCS-2 が UTF-8 になった経緯については検索してください)

もう 1 つ言及すべき点は BOM (Byte Order Mark) です。ファイルを保存するときに、ファイルで使用されているエンコーディングが保存されないため、保存時に使用したエンコーディングを記憶し、そのエンコーディングを使用してファイルを開く必要があります。 (メモ帳ではファイルを開くときにエンコードを選択できないと言いたいかもしれません。最初にメモ帳を開いてから、「ファイル」>「開く」を使用して確認することもできます。) UTF では、独自のエンコードを表す BOM が導入されています。これは、次に読み取られるテキストに使用されるエンコーディングが、対応するエンコーディングであることを意味します:

BOM_UTF8 'xefxbbxbf'

BOM_UTF16_LE 'xffxfe'

BOM_UTF16_BE 'xfexff'

すべての

editor

BOM が書き込まれるわけではありません。ただし、BOM がない場合でも Unicode を読み取ることはできますが、MBCS エンコードと同様に、特定のエンコードを指定する必要があります。指定しないとデコードが失敗します。

UTF-8 には BOM が必要ないという話を聞いたことがあるかもしれませんが、これは真実ではありません。BOM がない場合、ほとんどのエディターはデフォルトのエンコーディングとして UTF-8 を読み取ります。保存時にデフォルトで ANSI (MBCS) を使用するメモ帳でも、ファイルの読み取り に正常にデコードできた場合は、まず UTF-8 テスト エンコードが使用されます。メモ帳のこのぎこちないアプローチによりバグが発生しました。新しいテキスト ファイルを作成して「姹姧」と入力し、ANSI (MBCS) を使用して保存すると、再度開くと「Han a」になる可能性があります。試してみてください:)

2 . Python2.x

2.1のエンコーディングの問題

strとunicodeは両方ともbasestringのサブクラスです。厳密に言えば、str は実際にはバイト文字列であり、Unicode でエンコードされたバイトのシーケンスです。 UTF-8 でエンコードされた str '汉' で len()

関数を使用すると、実際には UTF-8 でエンコードされた '汉' == 'xE6xB1x89' であるため、結果は 3 になります。

unicode は実際の

string であり、正しい文字エンコーディングと len(u'汉') == 1 を使用してバイト文字列 str をデコードすることによって取得されます。

2 つのベースストリング インスタンス メソッド encode() と decode() を見てみましょう。str と unicode の違いを理解したら、これら 2 つのメソッドを混同することはなくなります。 encode() メソッドを呼び出すのは間違いですが、実際には Python は例外

をスローしませんが、同じ内容で異なる ID を持つ別の str を返します。これは Unicode で decode() メソッドを呼び出す場合にも当てはまります。 encode() と decode() がそれぞれ unicode と str に配置されず、両方とも Basestring に配置される理由がよくわかりません。しかし、このような状況なので、間違いを犯さないように注意しましょう。

2.2. 文字エンコーディングの宣言 ソースコードファイルで非 ASCII 文字が使用されている場合、次のようにファイルのヘッダーで文字エンコーディングの宣言を行う必要があります:

# coding: UTF-8
 
u = u'汉'
print repr(u) # u'\u6c49'
s = u.encode('UTF-8')
print repr(s) # '\xe6\xb1\x89'
u2 = s.decode('UTF-8')
print repr(u2) # u'\u6c49'
 
# 对unicode进行解码是错误的
# s2 = u.decode('UTF-8')
# 同样,对str进行编码也是错误的
# u2 = s.encode('UTF-8')
ログイン後にコピー

実際には、Python はチェックするだけです。 #、コーディングおよびエンコード文字列、その他の文字は、美観のために追加されます。さらに、Python では多くの文字エンコーディングが使用でき、大文字と小文字を区別しないエイリアスも多数あります。たとえば、UTF-8 は u8 と記述できます。 http://docs.python.org/library/codecs.html#standard-encodings を参照してください。

もう 1 つ注意すべき点は、宣言されたエンコーディングは、ファイルが実際に保存されるときに使用されるエンコーディングと一致している必要があるということです。そうでないと、コード解析例外が発生する可能性が高くなります。現在の IDE は通常、この状況を自動的に処理し、宣言を変更すると宣言されたエンコーディングで保存されますが、テキスト エディター コントローラーは注意する必要があります:)

2.3. ビルドされたファイルを使用してファイルを開くとき。 -open() メソッドでは、read() は str を読み取ります。読み取り後に decode() するには正しいエンコード形式を使用する必要があります。 () を記述するとき、パラメータが Unicode の場合は、書きたいエンコーディングを使用して encode() に渡す必要があります。それが他のエンコーディング形式の str である場合は、最初に str のエンコーディングを使用して decode() する必要があります。それを Unicode に変換し、書かれたエンコーディングを encode() に使用します。 Unicode をパラメータとして write() メソッドに直接渡すと、Python はまずソース コード ファイルで宣言された文字エンコーディングを使用してエンコードしてから書き込みます。

#-*- coding: UTF-8 -*-
ログイン後にコピー

さらに、モジュール コーデックには、ファイルを開くためのエンコーディングを指定できる open() メソッドが用意されており、このメソッドを使用して開かれたファイルは unicode を読み取って返します。書き込みの際、パラメータが Unicode の場合は、open() で指定されたエンコーディングを使用してエンコードされてから書き込まれます。パラメータが str の場合は、ソース コード ファイルで宣言された文字エンコーディングに従って Unicode にデコードされてから実行されます。前述の操作。組み込みの open() と比較して、このメソッドはコーディング上の問題が発生しにくいです。

# coding: UTF-8
 
f = open('test.txt')
s = f.read()
f.close()
print type(s) # <type &#39;str&#39;>
# 已知是GBK编码,解码成unicode
u = s.decode('GBK')
 
f = open('test.txt', 'w')
# 编码成UTF-8编码的str
s = u.encode('UTF-8')
f.write(s)
f.close()
ログイン後にコピー

2.4. エンコーディング関連のメソッド

sys/locale モジュールは、現在の環境でデフォルトのエンコーディングを取得するためのメソッドをいくつか提供します。

# coding: GBK
 
import codecs
 
f = codecs.open('test.txt', encoding='UTF-8')
u = f.read()
f.close()
print type(u) # <type &#39;unicode&#39;>
 
f = codecs.open('test.txt', 'a', encoding='UTF-8')
# 写入unicode
f.write(u)
 
# 写入str,自动进行解码编码操作
# GBK编码的str
s = '汉'
print repr(s) # '\xba\xba'
# 这里会先将GBK编码的str解码为unicode再编码为UTF-8写入
f.write(s)
f.close()
ログイン後にコピー

3. いくつかの提案

3.1. 文字エンコーディング宣言を使用し、同じプロジェクト内のすべてのソース コード ファイルで同じ文字エンコーディング宣言を使用します。

これはやらなければなりません。

3.2. str を放棄し、すべてに Unicode を使用します。

引用符を押す前に u を押してください。最初は慣れないので、戻って修正するのを忘れることがよくありますが、これを行うとコーディングの問題の 90% を減らすことができます。エンコードの問題が深刻でない場合は、この記事を参照する必要はありません。

3.3. 組み込みの open() の代わりに codecs.open() を使用します。

エンコードの問題が深刻でない場合は、この記事を参照する必要はありません。

3.4. 絶対に避けるべき文字エンコーディング: MBCS/DBCS および UTF-16。

ここで言及されている MBCS は、GBK やその他のものを使用できないという意味ではなく、プログラムがまったく移植可能でない場合を除き、Python で「MBCS」と呼ばれるエンコーディングを使用すべきではないという意味です。

Python のエンコーディング「MBCS」と「DBCS」は同義であり、現在の

Windows 環境

で MBCS によって参照されるエンコーディングを指します。 Python の Linux 実装にはそのようなエンコーディングがないため、Linux に移植すると必ず例外が発生します。さらに、Windows のシステム領域セットが異なる限り、MBCS が参照するエンコーディングも異なります。セクション 2.4 でさまざまな領域を設定してコードを実行した結果:

#中文(简体, 中国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\xba\xba'.decode('mbcs'): u'\u6c49'
 
#英语(美国)
#sys.getdefaultencoding(): UTF-8
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
 
#德语(德国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\xba\xba'.decode('mbcs'): u'\xba\xba'
 
#日语(日本)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh_CN', 'cp932')
#locale.getpreferredencoding(): cp932
#'\xba\xba'.decode('mbcs'): u'\uff7a\uff7a'
ログイン後にコピー

可见,更改区域后,使用mbcs解码得到了不正确的结果,所以,当我们需要使用'GBK'时,应该直接写'GBK',不要写成'MBCS'。

UTF-16同理,虽然绝大多数操作系统中'UTF-16'是'UTF-16-LE'的同义词,但直接写'UTF-16-LE'只是多写3个字符而已,而万一某个操作系统中'UTF-16'变成了'UTF-16-BE'的同义词,就会有错误的结果。实际上,UTF-16用的相当少,但用到的时候还是需要注意。

以上がPython 文字エンコーディングの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート