最近『meya.ai』をいじっていて、Pythonになんちゃって入門しました。
初心者として戸惑ったのが文字列の扱い。
print 'Hello,World' print u'Hello,World'
「u」ってなんですかね。 ということで、ザックリとまとめてみます。
※独学入門の初心者のため、間違えているところ多数の可能性があります。
注意
私はPython2.7を使っています。 軽く調べたところPython3.x系では全然違うようなので注意してください。
「文字型」と「ユニコード型」
Python2.xにおいては、文字列を表す型に「文字型」(str)と「ユニコード型」(unicode)の2種類が存在します。
「u」が付いていないのが「文字型」、付いているのが「ユニコード型」です。
print type('abcd') #=> <type 'str'> print type(u'abcd') #=> <type 'unicode'>
何が違うの?
ザックリ言うとこういうこと。
# -*- coding:utf-8 -*- #これはAsciiなのでどちらも一緒。 print len('abcd') #=> 4 print len(u'abcd') #=> 4 #これはマルチバイト(UTF-8)なので、文字型はバイト数になる。 print len('あいうえ') #=> 12 print len(u'あいうえ') #=> 4
要するにPython2.xでは文字型と言いつつもそれはバイトやでってことです。
で、どっち使えばいいの?
単純に「文字列処理ができるユニコード型を使っておけばいいじゃん」とは思うのですが、やはり注意が必要です。
最たる例が標準出力とファイル出力です。 以下のtest.pyというプログラムを用意します。
# -*- coding:utf-8 -*- #標準出力 text = u'あいうえお' print text #ファイル出力 f = open('test.txt','w') f.write(text) f.close()
これをターミナル上で実行すると、ファイル出力がエラーとなります。
$ python test.py あいうえお Traceback (most recent call last): File "test.py", line 6, in <module> f.write(text) UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
なぜか。
実はprint実行時にはPythonが「出力先の文字コードはUTF-8だね!」と判断して、UTF-8の文字型に変換してくれているんですね。 標準出力の文字コードはsysオブジェクトに値が格納されておりそいつを基に判定するのだと思います。
# -*- coding:utf-8 -*- import sys print sys.stdout.encoding #=> UTF-8 #だからこの値がasciiだとprintもエラーになる。 import codecs sys.stdout = codecs.getwriter('ascii')(sys.stdout) print 'あいうえお' #=>UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
一方でf.writeでは「文字コードの指定ないからようわからん。asciiでいいやろ。」と考えasciiに変換しようとするのですが、当然日本語には対応できずエラーとなります。
そのためファイル出力を行うにあたっては、
のどちらかを実施する必要があります。
# -*- coding:utf-8 -*- import codecs text = u'あいうえお' #文字型へエンコード f = open('test1.txt','w') f.write(text.encode('utf-8')) f.close #エンコードを指定してファイルを開く(要codecsオブジェクト) f = codecs.open('test2.txt','w','utf-8') f.write(text) f.close
$ python test.py $ cat test1.txt あいうえお $ cat test2.txt あいうえお
結論:入門するならPython3
Python3だとunicode型が無くなり、「文字型とバイト型」というわかりやすい構成になっているようです。 私は何故か2.7で入門してしまいましたが、「u」とかいちいち付けるの面倒なんでこれから始める人は3.x系がおすすめです。
参考にさせていただきました。
私の記事よりも圧倒的に細かく・詳しく書いてあります。
Pythonの日本語処理
http://www.kabipan.com/computer/python/unicode.html
Python2のstr/unicodeとencode/decode
Python機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)
- 作者: Sebastian Raschka,株式会社クイープ,福島真太朗
- 出版社/メーカー: インプレス
- 発売日: 2016/06/30
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (4件) を見る
確かな力が身につくPython「超」入門 (確かな力が身につく「超」入門シリーズ)
- 作者: 鎌田正浩
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2016/03/16
- メディア: Kindle版
- この商品を含むブログを見る