主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Python: 2.7から3.xへの移行 文字列編

                
tags: python
 前回にバイナリデータを処理してたスクリプトを、2.7対応から3.4にも対応するように書き換えた。
Python2.7でバイナリデータを処理してたスクリプトを3.4で使えるように書き換えてみる

3.4にバージョンを進めるにあたって文字列にも変更があった。ぼくが初めてPythonを使ったとき、文字列周りのことはなんとなくでやるのが難しかったので事前にキチンとやっておくことにする。

 2.7ではstr型とunicode型があった。どっちも文字列を表現するのに使われた。
 unicode型は名前のとおりunicode規格にそった文字の表現だ。unicode型の世界は規格が一本しか存在していない世界なので文字化けなどは無縁。str型はASCIIやらUTF-8やらなにかしらの規格に従って表現されている文字列だ。str型の世界で文字列表現のための規格は複数あり、あるstr型の文字列データがどの規格で表現されているかを自分で把握していなければ、マルチバイト文字でおかしな文字化けに出くわしたり目的の処理が成功しなかったり。
 たとえばWin7環境Python2.7で文字列"あいう"のなかから"う"の位置を知りたいとき、str型でエンコード規格を把握せずにそれをやるのは望ましくない。
s = u"あいう" # unicode型文字列"あいう"を用意
s1 = s.encode("utf-8") # str型で欲しいのでUTF-8でエンコード、str型に変換される
print(s1.find("う"))

 変数s1に入った文字列も、findメソッドで引数にしている文字列もstr型である。これで平仮名"う"の位置を特定できれば、画面には2が表示されるはず。だがおそらく表示されるのは、見つからなかったという意味の-1だ。
 s1はUTF-8でエンコードされている。対してfindメソッドの引数"う"はなにも指定されていないため、Win7+Python2.7のデフォルトであるCP932がエンコードに適用されている。そのためにs1に入っている"う"は"\xe3\x81\x86"というバイナリで表現されるが、引数で渡した"う"は"\x82\xa4"で表現されるという差異がうまれ、文字列検索でも見つからなくしている。どっちもstr型だったのに。というわけでなにも把握せずにstr型でマルチバイト文字を含む文字列を扱うにはちょっと問題があった。

 3.4ではunicode型が新しいstr型に吸収され、文字列は新しいstr型で扱ってくださいということになった。新しいstr型の中身はunicode文字列だ。文字列の表現方法が一本に統一されているので、さっきのような齟齬は起きない。str型"あいう"からstr型で"う"を探そうとすれば、絶対に見つかる。
 文字列を宣言すると、それはデフォルトでstr型として扱われる。2.7でつけていたプレフィクスuを外せる。
u"あいう" == "あいう"

 UTF-8でエンコードされた出力が欲しければ、これまでと同じようにエンコードをかけてやればいい。ただし出力されるのはstr型でなくbytes型。
"あいう".encode("utf-8")

 個人的には2.7のunicode型が3.4でstr型として実装され、2.7のstr型が3.4でbytes型になったような印象を受ける。違うところもあるけどおおまかなところでは。とりあえず文字列を扱う型が統一されたのはありがたいところ。
参考:http://diveintopython3-ja.rdy.jp/strings.html#byte-arrays
http://diveintopython3-ja.rdy.jp/porting-code-to-python-3-with-2to3.html#unicodeliteralx
            

コメントの投稿

非公開コメント

プロフィール

Matoba

Author:Matoba

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。