[再版] python2.7の文字エンコーディングの問題

https://www.cnblogs.com/liaohuiqiang/p/7247393.html

1 ascii、unicode、utf8


1.1アスキー

最初のコードは1271文字のみで、英語の文字、数字、句読点、その他の記号が含まれています。1バイトは1文字を表します

1.2 unicode(ユニコード)

1バイトでは十分ではありません。世界中にさまざまな言語の文字をエンコードする必要があるため、unicodeはすべての文字に一意のエンコードを設定します。通常使用二言セクションは文字を表します(使用するいくつかの珍しい単語)4バイト)。したがって、理解しておくべきことの1つは、以下に示すunicodeエンコーディングです。2バイトエンコーディング(1文字あたり2バイト)。

1.3 uft8

以下のためにasciiこれらの文字エンコーディング、ちょうど1、バイトunicodeこれらの文字も設定されている与える2記事が英語である場合、(バイトascii文字)を、あなたは多くのスペースを無駄に(本来は1それがで、保存することができるバイト2Aバイト)、そのように生成されutf8ます。utf8可変長符号化、バイトの長さに応じてシンボルの変更、あるasciiにエンコードされ1たバイト、文字は通常にエンコードされている3希少な文字の一部がにエンコードされ、バイト4~6バイト。

コンピュータのメモリでは、unicodeコーディングは均一に使用されます。

ではpythonunicodeファイルの保存およびファイルの読み取り時に、プログラムのプロセスでコーディングを均一に使用することをお勧めしますutf8utf8対応するdecode合計、ディスクファイルの読み取りおよび書き込み時に使用されますencode)。

2エンコードステートメント


pythonデフォルトでは、asciiエンコーディングはソースファイルの解釈に使用されます。

ソースファイルに非ASCIIコード文字が含まれてencodingいる場合、最初に宣言されていないとエラーが報告されます。

これはutf8、インタープリターutf8にファイルコードの読み取り指示するものとして宣言できますが、現時点では、ソースファイルに中国語が含まれている場合、エラーは報告されません。

# encoding=utf8 如果不加这一行会报错
print '解释器用相应的encoding去解释python代码'

python2.7の3 strおよびunicode


python2.7とには通常、2種類の文字列がunicodeありstrます。

  • strバイトコードの場合、文字列は特定のエンコーディングに従ってバイトに変換されますが、現時点では、文字とバイトの間に1対1の固定の対応はありません。
  • unicodeunicodeエンコードされた文字列であり、現時点では、文字は2バイトに1対1で対応しています。
  • 直接割り当て列型strstrバイト文字列は、最初の後に続くencoding1バイトにエンコードします。
  • 割り当てるときは、文字列の前に1つ追加しu、タイプはunicodeであり、それに従って直接unicodeエンコードします。
s1 = '字节串'
print type(s1) #输出 <type 'str'>,按照开头的encoding来编码成相应的字节。
print len(s1) #输出9,因为按utf8编码,一个汉字占3个字节,3个字就占9个字节。

s2 = u'统一码'
print type(s2) #输出 <type 'unicode'>,用unicode编码,2个字节1个字符。
print len(s2) #输出3,unicode用字符个数来算长度,从这个角度上看,unicode才是真正意义上的字符串类型

現実的な例を見てみましょう、たとえば、ファイルから「学習」している最後の2つの単語のすべての単語を見つける必要があります。

s = '机器学习'
s[-2:] == '学习‘ 
# 返回false,平时写程序可能会以为相等。
# 这里的”学习是用开头的encoding声明解释的,我开头用的是utf8,汉字占3个字节,
# 所以“学习”占了6个字节),而s[-2:]取的是最后两个”双字节“,所以不相同。

s = u'机器学习'
s[-2:] == u'学习’ 
# 返回true,这也是为什么说unicode是真正意义上的字符串类型。因为使用的是unicode,\
# ”学习“占的是两个”双字节“,一个"双字节“一个字。

中国語の文字列を頻繁に扱う人にとって、unicodeこの落とし穴は統合使用によって回避できます

一部の文字列処理関数strも使用できますが、エンコードの問題を処理する関数でなければなりません。

4 python2.7でのエンコードとデコード


エンコードの通常の使用法:Unicode文字列型をエンコードして、バイト文字列str型を取得します。それはunicode->エンコード(指定されたエンコードに従って)-> strです。

デコードの通常の使用:Unicodeタイプを取得するためにstrタイプをデコードします。それはstr->デコード(指定されたエンコーディングに従って)->ユニコードです。

注:エンコードとデコードの両方でエンコードを指定する必要があります。

エンコード時に元のエンコードとエンコードする新しいエンコード方法を知る必要があるため、2種類のエンコードが使用されます。デフォルトではUnicodeが存在するため、別のエンコード方法を指定する必要があります。デコード時も同様です。

これらの2つの方法は、指定されたエンコーディングでunicodeとstrの間で変換することです。

s3 = u'统一码'.encode('utf8')
print type(s3) # 输出 <type 'str'>

s4 = '字节串'.decode('utf8')
print type(s4) #输出 <type 'unicode'>

encode不適切な使用:strタイプが必要なencodeためタイプが使用されencodeますunicode。現時点では、pythonデフォルトのシステムを使用しdecodeunicodeタイプをエンコードし、指定したエンコードを使用しますencode(ここでのシステムコードは冒頭encodingはないことに注意してください。特定の例については、以下のポイント5を参照してください)

decodeunicodeタイプの不適切な使用:タイプのdecode場合、pythonデフォルトのシステムを使用しencodestrタイプをエンコードし、指定したコードを使用しますdecode

したがって、対応するシステムのデフォルトのエンコーディングを変更した場合、それが正常に使用されていなくても、エラーは報告されません。でも、もう少し回って、これは嫌いです。

5システムのデフォルトのエンコーディングを変更する


システムはデフォルトasciiでエンコーディングを使用し、それに応じて変更する必要があります。

このエンコーディングと最初のencoding違いは、最初encodingはファイルコンテンツのエンコーディングです。

ここで符号化の一部であるpython方法ように、デフォルトで使用される符号化、str行うencodeときに最初のデフォルトのdecodeようなファイルの書き込みなどのコードwriteencodeコードが(午前7時00分以下の原稿読取装置のセクションを参照します)

import sys
reload(sys)
sys.setdefaultencoding('utf8')

s = '字节串str'

s.encode('utf8')
#等价于
s.decode(系统编码).encode('utf8')

システムのデフォルトのエンコーディングが機能する別の例を見てみましょう。

import sys
print sys.getdefaultencoding()  # 输出ascii

s = 'u华南理工大学'
print s[-2:] == '大学'   # 返回False,并有warning提醒

reload(sys)
sys.setdefaultencoding('utf8')

print s[-2:] == '大学'  # 返回True 

結果によると、比較pythonを使用==する場合、最初の演算子がそうでunicodeあり、2番目の演算子がそうでない場合、システムのデフォルトのエンコーディングを自動的に使用して、2番目の演算子を支援しますdecode

PS:なぜそれが必要なのreload(sys)ですか?まず、reload前のimportモジュールをリロードするために使用されます。

これは、リロードする必要がありますsys:理由はpython、ロード・モジュール内で削除(おそらくセキュリティ上の理由のため)の方法なので、彼らが必要とするこのモジュールを。syssetdefaultencodingreloadsys

6ファイルのエンコーディングを表示する

import chardet
with open(filename,'r') as f:
    data = f.read()
    return chardet.detect(data)

7ファイルの読み書き


7.1オープン

最初に覚えておかなければならないのは、これら2つのファイル読み取りと書き込みのゲートstrは、1バイトのタイプであることです。

python組み込みのデフォルトopenでは、ファイルを読み取るときにバイト文字列strの形式でバイトを1つずつ読み取ります。読み取り後、正しいエンコーディングを使用しdecodeて正しいユニコード形成する必要があるため、ファイル内の元のエンコーディングを知る必要があります。

これはファイルを書き込む際の理由でもあります。strタイプごとにバイトの形式で書き込まれます。これはstr特定のエンコード方式でエンコードされutf8ます。正しいエンコード方式でのエンコードに注意してください。通常、ファイルはエンコード後に書き込まれます。

unicodeタイプで書き込む場合pythonunicodeエンコーディングはシステムのデフォルトのエンコーディングに従ってstr なり、ファイルに書き込まれます。あなたがファイルに書き込む必要strがあるのはstrそれを書くことだけなので、私があなたをstr再び書くように変換するのではありません

単純な原則は、可能な限りstr書き込みを使用し、デフォルトのエンコーディングを使用しないことです。そのため、最初にデフォルトのエンコーディングを変更する必要はありません。

7.2コーデックを開く

Pythonのモジュールcodecsopenメソッドエンコードを指定できます。保証する読み書きされたバイトすべては、この指定されたコードに従ってコード化されています。

ファイルが読み込まれたときにこのように、私が読み出されますstrエンコードされた指定decodeunicode

ファイルを書き込む場合:それがある場合はunicode指定されたエンコーディングに基づいて、encodestr、書き込み、それがある場合はstr、符号化システムに応じてデフォルトするstrことdecodeを得unicode、その後指定されたエンコーディングに応じて、encodestr執筆。

単純な原則は、可能な限りunicode書き込みを使用し、デフォルトのエンコーディングを使用しないことです。そのため、最初にデフォルトのエンコーディングを変更する必要はありません。

ファイルを読み書きする他の方法については、エンコーディングの問題を確認するためにデバッガーが必要であることに注意してください。たとえば、PythonでExcelを読み取ると、strではなく直接Unicodeを読み取ります。

8一般的な取り扱いポイント


  1. まず、ソースファイルのencodingデフォルトのエンコーディングとシステムのデフォルトのエンコーディングをutf8
  2. プログラム実行中の均一使用unicodeタイプ
  3. ファイルの読み取りと書き込み(python組み込みのデフォルトopen)の場合、strそれに応じてstr encode合計decodeできます

要約すると:

  • 対応するデフォルトのエンコーディングをに設定しますutf8
  • ファイルを読み取ってstrタイプを取得しますstr -> decode('utf8') -> unicode
  • プログラム処理:使用unicode
  • ファイルを書き込む:タイプを指定してファイルunicode -> encode('utf8') -> str書き込むstr
  • もちろん、前提条件は、ファイルがutf8ソースファイルと読み取りおよび書き込みデータファイルを含む形式であることです。

また言いたいこと:

unicodeこれは、プログラムを記述するプロセスでを均一に使用するための提案すぎません。これは、unicode文字列を処理するときの問題を軽減できるためです。

unicode問題があると感じた場合は、通常の統一的なutf8コーディングを検討できますstr。いくつかの問題をunicode再度使用する必要がありunicodeます。コーディングの問題が発生た場合は、統一的なunicode問題がないかどうかを考えることができますunicode。状況)

71件のオリジナル記事を公開 56件の賞賛 90,000回以上の閲覧

おすすめ

転載: blog.csdn.net/baidu_26646129/article/details/104725887