python unicode符号化整理

3959 ワード

unicodeとutf-8の関係
unicodeはcharacter setです
  • character setは、unicodeのAが0041、漢字「私」が「6211」
  • のように、各文字を数字に対応する集合である.
  • unicodeは大きな集合で、世界のすべての文字をほぼカバーしており、現在の規模では100万文字を収容することができます.

  • utf-8はunicodeストレージの実現方式である
    unicodeは文字に対応する数字のみを定義しますが、これらの数字をどのように格納するかは規定されていません.例えば、中国語の「私」の字のように格納するには2バイトが必要ですが、英語のアルファベットAは1バイトしか必要ありません.他の文字には3-4バイトが必要な場合があります.
  • 各文字を3バイトまたは4バイトで格納することを統一的に規定すると、各英語文字は必然的に2~3個の0を追加する必要があり、これは格納に大きな浪費である.
  • 各文字が実際に必要なバイト数で格納されると、コンピュータは3つのバイトが3つの文字を表すのか、1つの文字を表すのか分からない.

  • utf-8はunicode符号化記憶の実現形態であり、同様にutf-16,utf-32もある.
    utf-8は最も広く使用されている符号化方式であり、長くなる符号化方式を採用し、1〜4バイトを用いて1文字を表すことができる.utf−16は2バイトまたは4バイト、utf−32は4バイトで表される.エンコードルールは次のとおりです.
  • は、単一バイトのシンボルに対して、バイトの第1ビットを0とし、後の7ビットをこのシンボルのunicodeコードとする.したがって、UTF-8符号化は、英字ではASCII符号と同じである.
  • nバイトのシンボル(n>1)については、1バイト目の前nビットが1、n+1ビット目が0、後バイトの前2ビットが一律に10とする.残りの言及されていないバイナリビットは、すべてこの記号のunicodeコードです.

  • python 2のstrとunicode
    python 2には、byte string (str)unicode string (unicode)の文字列タイプがあります.
    >>> s = '  '
    >>> s
    '\xe7\xbe\x8e\xe7\x9a\x84'
    >>> s = u'  '
    >>> s
    u'\u7f8e\u7684'
    >>> s = '  '
    >>> s.decode('utf-8')
    u'\u7f8e\u7684'

    上記の出力では、最初のsのタイプはstrであり、印刷された内容はutf-8符号化された内容である.2番目のsのタイプはunicodeで、印刷された2バイトの数字はそれぞれ2つの漢字「美しい」を表しています.encodeおよびdecodeはstrおよびunicodeの2つのタイプの相互変換を提供する.
  • encode unicodeをstr(byte string)
  • に変換
  • decodeはstr(byte string)をunicode
  • に変換する
    本質的にstrは格納されたバイトシーケンスであり、ascii、gbk、utf-8などのいずれかである可能性があり、decodeを呼び出すことでunicodeに変換することができ、デフォルトのdecode符号化はasciiである.strでどの符号化が使われているかは、そのシーンによってlocale、ファイル符号化などと関係があります.
    テキストファイル、エディタの処理
    #!/usr/bin/env python
    # -*- coding: GBK -*-
    
    s = u'  '
    print repr(s)
    print repr(s.encode('GBK'))

    例えば上記のファイルenc.py、保存時に を選択するのがGBKであり、プログラムファイルも本質的にファイルであり、ある外部のアプリケーションを使ってそれを開くと(エディタやpython解釈器など)、外部アプリケーションはそのファイルの符号化フォーマットを知らないので、
    この場合、3つの状況があります.
  • アプリケーションは、UTF−8またはASCIIなどのデフォルトの符号化方式を使用して解析する.python解釈器のデフォルトはASCIIで、エディタは自分で設定できます.
  • アプリケーションは、ファイル内のバイト内容に基づいて、符号化方式を自動的に検出する.
  • テキストファイルは、アプリケーションがどのような符号化方式で復号するかを示す.例えば、# -*- coding: GBK -*-は、解釈器にGBKを使用して復号することを通知する.

  • テストして、# -*- coding: GBK -*-を削除した後、python enc.pyを実行し、出力:
       File "enc.py", line 4
     SyntaxError: Non-ASCII character '\xd6' in file enc.py on line 4, but no encoding declared;

    vimでファイルを開いてみると、vimのデフォルトのファイル符号化方式がUTF-8に設定されているため、『中国語』の2文字が文字化けして表示されます.
    #!/usr/bin/env python
    # -*- coding: GBK -*-
    
    s1 = u'  '
    
    print repr(s1)
    print repr(s1.encode('GBK'))
    
    s2 = '  '
    
    print repr(s2)
    print repr(s2.decode('GBK'))

    出力結果:
    u'\u4e2d\u6587'
    '\xd6\xd0\xce\xc4'
    '\xd6\xd0\xce\xc4'
    u'\u4e2d\u6587'

    ここから,s 2にはbyte形式のファイルから読み出されたGBK符号化の内容が格納されていることが分かる.
    次のコードを見ると、プログラムファイルutf8_enc.pyはUTF-8符号化に保存されています.
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    s1 = u'  '
    
    print repr(s1)
    print repr(s1.encode('GBK'))
    
    s2 = '  '
    
    print repr(s2)
    print repr(s2.decode('GBK'))

    出力:
    u'\u4e2d\u6587'
    '\xd6\xd0\xce\xc4'
    '\xe4\xb8\xad\xe6\x96\x87'
    Traceback (most recent call last):
      File "unicode_enc.py", line 12, in 
        print repr(s2.decode('GBK'))
    UnicodeDecodeError: 'gbk' codec can't decode bytes in position 2-3: illegal multibyte sequence

    ここでも同様に、s 2に格納されているのは、ファイル格納の符号化UTF-8のbyte符号であることが分かる.
    References
    http://www.rrn.dk/the-differe...http://www.ruanyifeng.com/blo...https://docs.python.org/2/how...http://yergler.net/2012/bytes...