Python のエンコーディングが覚えられないですし、おすし

powered by Fotopedia




Python で日本語文字列を使うときの注意点は本でも Web でもいろんなところで紹介されています

http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/python/encoding.html
http://python.matrix.jp/tips/string/encoding/
http://lab.hde.co.jp/2008/08/pythonunicodeencodeerror.html

理屈はわかるけど結局自分が悩んでいるのは
encode/decode が unicode から str と str から unicode
どっちがどっちだったけって? ってところだ

慣れとか覚えろって話なんだけど、覚えられませんでした、はい、残念!!!

だったら覚えられる名前にすればいいんじゃないかということで

としてみました。これならなんとか覚えられそうです

# -*- coding: utf-8 -*-
import locale
locale.setlocale(locale.LC_ALL, '')

def to_u(str_value, enc = locale.getpreferredencoding()):
    return unicode(str_value, enc)

def to_s(unicode_value, enc = locale.getpreferredencoding()):
    return unicode_value.encode(enc, 'replace')

was_u   = u'わっしょい'

was_s   = to_s(was_u)
was_u   += to_u(was_s)

print('type=%s, repr=%s' % ( type(was_s), repr(was_s) ))
# type=<type 'str'>, repr='\x82\xed\x82\xc1\x82\xb5\x82\xe5\x82\xa2'
print('type=%s, repr=%s' % ( type(was_u), repr(was_u) ))
# type=<type 'unicode'>, repr=u'\u308f\u3063\u3057\u3087\u3044\u308f\u3063\u3057\u3087\u3044'

print(was_s) # わっしょい
print(was_u) # わっしょいわっしょい


さて調べてるところで標準入出力をラップして文字コードを指定する方法が紹介されていれました

標準入出力(sys.stdin, sys.stdout)で用いる文字コードを指定するには

http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/python/encoding.html  

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import codecs

sys.stdin  = codecs.getreader('euc_jp')(sys.stdin)
sys.stdout = codecs.getwriter('shift_jis')(sys.stdout)

for line in sys.stdin:
    print line,


そちらで紹介されているコードを改変して # ここに追加 ってところにいれると
print に str を渡したときエラーになるようようになりました

# -*- coding: utf-8 -*-
import locale
locale.setlocale(locale.LC_ALL, '')

def to_u(str_value, enc = locale.getpreferredencoding()):
    return unicode(str_value, enc)

def to_s(unicode_value, enc = locale.getpreferredencoding()):
    return unicode_value.encode(enc, 'replace')

was_u   = u'わっしょい'

was_s   = to_s(was_u)
was_u   += to_u(was_s)

print('type=%s, repr=%s' % ( type(was_s), repr(was_s) ))
print('type=%s, repr=%s' % ( type(was_u), repr(was_u) ))

print(was_s)        # ここはOK
print(was_u)

# ここに追加
import sys
import codecs
sys.stdin  = codecs.getreader(locale.getpreferredencoding())(sys.stdin)
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)

try:
    print(was_s)    # ここはNG
except UnicodeDecodeError, ude:
    print('type=%s, err=%s' % ( type(was_s), str(ude) ))
    # type=<type 'str'>, err='ascii' codec can't decode byte 0x82 in position 0: ordinal not in range(128)

print(was_u)


これがなんでだか分からない。ああ、ほんとに残念だ....