PYTHON-ステップ-符号化処理

16666 ワード

一般文字列は、Unicode文字列に様々な方法で符号化できます.具体的には、どの符号化を選択したかによって異なります.unicodestring=u「Hello world」#Unicodeを一般Python文字列に変換します.「encode」utf 8 string=unicodestring.encode("utf-8")   asciistring = unicodestring.encode("ascii")   isostring = unicodestring.encode("ISO-8859-1")   utf16string = unicodestring.encode("utf-16")#一般Python文字列をUnicode:"decode"plainstring 1=unicode(utf 8 string,"utf-8")plainstring 2=unicode(asciistring,"ascii")plainstring 3=unicode(isostring,"ISO-859-1")plainstring 4=unicode(utf-16 string,"utf-16")assertplainstring 1=plainstring 2=plainstring 2=plainstring 3=plainstring 3=plainstring 3=plainstring 3=plainstring 3=plainstring 3=plainstring 3=plainstring 3=plainstring 3=pla义齿
------------------------------------------------------------------------
pythonで中国語を処理する場合、ファイルやメッセージ、httpパラメータなどを読み込む
実行すると、文字列処理、ファイルの読み書き、print)
そして、多くの人はencode/decodeを呼び出してデバッグし、なぜ文字化けしたのかを明確に考えていません.
デバッグ時に最も頻繁に発生するエラー
エラー1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128)

エラー2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

まず


文字セット、文字コードを理解するには、大体の概念が必要です.
ASCII|Unicode|UTF-8|など
文字コードメモ:ASCII、Unicode、UTF-8
宝を洗って技術のブログを検索します

strとunicode


strもunicodeもbasestringのサブクラスです
文字列かどうかを判断する方法があります
def is_str(s):
    return isinstance(s, basestring)

strとunicode変換
decodeドキュメント
encodeドキュメント
str  -> decode('the_coding_of_str') -> unicode
unicode -> encode('the_coding_you_want') -> str

区別する
strはバイト列で、unicodeが符号化(encode)されたバイトからなる
宣言方法
s = ' '
s = u' '.encode('utf-8')

>>> type(' ')
<type 'str'>

長さを求める(バイト数を返す)
>>> u' '.encode('utf-8')
'\xe4\xb8\xad\xe6\x96\x87'
>>> len(u' '.encode('utf-8'))
6

unicodeこそ本当の意味での文字列で、文字で構成されています
宣言方法
s = u' '
s = ' '.decode('utf-8')
s = unicode(' ', 'utf-8')

>>> type(u' ')
<type 'unicode'>

長さ(文字数を返す)を求めて、論理の中で本当に使いたいです
>>> u' '
u'\u4e2d\u6587'
>>> len(u' ')
2

結論
処理するのがstrなのかunicodeなのか、正しい処理方法(str.decode/unicode.encode)を使うのかがわかります
次はunicode/strかどうかを判断する方法です
>>> isinstance(u' ', unicode)
True
>>> isinstance(' ', unicode)
False

>>> isinstance(' ', str)
True
>>> isinstance(u' ', str)
False

単純原則:strにencodeを使用しないで、unicodeにdecodeを使用しないでください(実際にstrにencodeを使用することができますが、具体的には最後に、簡単を保証するために、お勧めしません)
>>> ' '.encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

>>> u' '.decode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

異なる符号化変換はunicodeを中間符号化として用いる
#s code_A str
s.decode('code_A').encode('code_B')

ファイル処理、IDEおよびコンソール


プロセスを処理して、このように使うことができて、pythonを1つの池と見なして、1つの入り口、1つの出口
入口では、すべてunicodeに変換され、プールではすべてunicode処理が使用され、出口では、ターゲット符号化に変換されます(もちろん、例外があり、処理ロジックで具体的な符号化が使用される場合があります)
 

 ,decode unicode

 ( , unicode)

encode 

 ( )

IDEとコンソールが間違っています.printの場合、符号化とIDE自体の符号化が一致しないためです.
出力時にコードを一致に変換すれば正常に出力できます
>>> print u' '.encode('gbk')
����
>>> print u' '.encode('utf-8')
 

推奨


ひょうじゅんコーディング
統一符号化、ある段階で発生する文字化けしを防止する
環境エンコーディング、IDE/テキストエディタ、ファイルエンコーディング、データベースデータテーブルエンコーディング
保証コードソースファイル符号化
これはとても重要です.
pyファイルのデフォルト符号化はASCIIであり、ソースファイルで非ASCII文字を使用する場合は、ファイルヘッダで符号化宣言ドキュメントを必要とする
宣言しない場合は、ASCII以外で発生するエラーを入力し、ファイルの1行目または2行目に置く必要があります.
File "XXX.py", line 3
SyntaxError: Non-ASCII character '\xd6' in file c.py on line 3, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

メソッドの宣言
# -*- coding: utf-8 -*-
 
#coding=utf-8

頭部がcoding=utf-8と宣言すると、a='中国語'はutf-8と符号化される.
頭部がcoding=gb 2312と宣言すると、a='中国語'はgbkと符号化される
so,同じプロジェクトのすべてのソースファイルヘッダは1つの符号化を統一し,宣言された符号化はソースファイルに保存された符号化と一致する(エディタ関連)
ソースコードで処理として使用されるハードコーディング文字列では、unicodeを統一して使用します.
そのタイプとソースファイル自体の符号化を分離し,独立して便利なプロセスにおける各位置処理に依存しない
if s == u' ':  #  s == ' '
    pass
#  s , unicode

以上の手順で完了したら、2つのunicodeと設定されたコードに注目するだけです(一般的にutf-8を使用します)
処理順序
1. Decode early
2. Unicode everywhere
3. Encode later

関連モジュールといくつかの方法


システムのデフォルトエンコーディングの取得と設定
>>> import sys
>>> sys.getdefaultencoding()
'ascii'

>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding('utf-8')
>>> sys.getdefaultencoding()
'utf-8'

str.encode('other_coding')
pythonでは、ある符号化strを直接encodeして別の符号化strにする
#str_A utf-8
str_A.encode('gbk')

 
str_A.decode('sys_codec').encode('gbk')
 sys_codec  sys.getdefaultencoding()  

「システムのデフォルト符号化の取得と設定」はここのstr.encodeと関連していますが、私は一般的にこのように使うことはめったにありません.主に複雑で制御できないと思っているのか、明確なdecodeを入力して、明確なencodeを出力するのが簡単だと思っています(個人的な観点)
chardet
ファイルコード検出、ダウンロード
>>> import chardet
>>> f = open('test.txt','r')
>>> result = chardet.detect(f.read())
>>> result
{'confidence': 0.99, 'encoding': 'utf-8'}

u文字列変換対応unicode文字列
>>> u' '
u'\u4e2d'

>>> s = '\u4e2d'
>>> print s.decode('unicode_escape')
 

>>> a = '\\u4fee\\u6539\\u8282\\u70b9\\u72b6\\u6001\\u6210\\u529f'
>>> a.decode('unicode_escape')
u'\u4fee\u6539\u8282\u70b9\u72b6\u6001\u6210\u529f'

python unicodeドキュメント
いりぐち
よし、しばらくはこれだけだから、はっきり言ってほしい.