<Python> 文字コードのめも

python3の場合、文字列は、うにこーどunicodeのコードポイントを並べたもの とのこと。
ようは、UTF-8のことらしい。

python2とは違うので注意!。
python2の例を参考するとはまる。

ファイルとかに書きだすということは、文字列をエンコードすることになる。

その1

文字列strから、各文字コードのバイト列bytesにするencodeには下記。

In [1]: 'あ'
Out[1]: 'あ'

In [2]: s = 'あ'

In [3]: type(s)
Out[3]: str

In [4]: s.encode('utf-8')
Out[4]: b'\xe3\x81\x82'

In [5]: type(s.encode('utf-8'))
Out[5]: bytes

In [6]: s.encode('sjis')
Out[6]: b'\x82\xa0'

バイト列を文字列にするdecodeには、

In [7]: b'\xe3\x81\x82'.decode('utf-8')
Out[7]: 'あ'

バイト列の形式があってないと、

In [8]: b'\xe3\x81\x82'.decode('sjis')
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-8-07f15d01637c> in <module>()
----> 1 b'\xe3\x81\x82'.decode('sjis')

UnicodeDecodeError: 'shift_jis' codec can't decode byte 0x82 in position 2: incomplete multibyte sequence

げろっちー。

その2

utf-8の形式のファイルをsjis環境で読み込む場合。
単純にやると、

In [80]: with open('utf8.txt', 'r') as f:
    ...:     s = f.read()
    ...:     
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-80-6b15acda41b2> in <module>()
      1 with open('utf8.txt', 'r') as f:
----> 2     s = f.read()
      3 

UnicodeDecodeError: 'cp932' codec can't decode byte 0x86 in position 8: illegal multibyte sequence

げろっちー。
なので、encodingを指定して、

In [81]: with open('utf8.txt', 'r', encoding='utf-8') as f:
    ...:     s = f.read()
    ...:     

In [82]: s
Out[82]: 'あいうえお\n\n'

できたー。

その3

メモ。
flaskさんで、request.form.get('text')で取ってきたデータを、
サーバserverサイドのunix linux環境にファイルとして書き出すsave場合。
requestからのデータが、Windowsからだと、SJIS shift-jisのようなので、
書き出す時は、encoding指定しないとエラーになる。

with open('hage.txt', 'w', encoding='utf-8') as f:
   f.write(request.form.get('text'))

としましょう。

参考サイト。

http://docs.python.jp/3/howto/unicode.html

Python 3誕生の理由 ― つまり、なぜunicode/str/bytesの仕様は変更されたのか | プログラミング | POSTD

Python3で文字列を処理する際の心掛け - Qiita