Ad

PythonのUnicodeに関する問題 anchor.png Edit

PythonでUnicodeをあつかうのはかなりやっかいです。 バージョン3では改善されましたが、バージョン2系ではUnicodeとstr型の二つに互換性がなく、つねにその文字列がstr型なのか、Unicodeなのか意識していないとエラーが出ます。 コンソール画面にテキストを表示する、というようなごく簡単な処理ですらエラーが出ます。

バージョン3以降を使えばよいのですが、ライブラリの対応状況などもありバージョン2系を使うことも多いのが実情です。

そんなときのUnicodeの取り扱いについて紹介します。

Page Top

Unicodeを実際に使うには anchor.png Edit

まず、ソースコードにUnicode文字列を書くためには、以下のコメントをソースファイルの先頭付近に入れておく必要があります。

# -*- coding: utf-8 -*-

これにより、Pythonはそのファイルでutf-8の文字コードが使われていると判断します。 ないとエラーになります。

実際にutf-8の文字列をソースに書くときは、

utfString = u"これはutfです"

というように、先頭に「u」をつけます。

標準出力でUnicodeを出力するなら、以下のように出力前に変換してやる必要があります。 こうしないとパイプで他のプログラムにデータを渡すときなどにエラーとなります。

import sys

sys.stdout = codecs.getwriter('utf_8')(sys.stdout)

標準入力や標準エラー出力も同様です。

sys.stdin = codecs.getreader('utf-8')(sys.stdin)
sys.stderr = codecs.getwriter('utf-8')(sys.stderr)

Unicodeとstrを変換するには、Unicode->strはdecode、str->Unicodeはencodeメソッドを使います。

utfString = u"これはUnicodeです"
strString = "これはstrです"


encodedUtf = utfString.encode("utf_8") #utfをstr
decodedStr = strString.decode("utf_8") #strをutf

print type(encodedUtf)
print type(decodedStr)

結果

<type 'str'>
<type 'unicode'>

逆にするとエラーとなります。

現実には使っているライブラリなどの引数や戻り値が、どれがunicodeなのかstrなのかいちいち覚えていられないので、エラーが出たらencodeかdecodeを行う、といった対応になります。

unicode、strどちらかわからない、またはどちらの可能性もあるとき、必ずunicodeの結果がほしいという場合には、isinstanceを使って以下のような関数を定義すると便利です。

def convertToUtf(s):
   if isinstance(s,unicode):
       return s
   return s.decode("utf_8")

するといつでもunicode文字列が得られます。strについても同様の関数が定義できるでしょう。

実際にバージョン2系で開発していると、Unicode関連のエラーはかなりイラッとさせられます。

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

このエラーを何度見たことかわからないくらいです。

根本解決として、早めにバージョン3以降に移るのがおすすめです。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom Powered by xpWiki
Counter: 2072, today: 1, yesterday: 0
初版日時: 2016-12-03 (土) 15:47:41
最終更新: 2016-12-05 (月) 11:36:52 (JST) (2660d) by njf
MenuBar
広告

ログイン

ユーザー名:


パスワード:





パスワード紛失

Portuguese | English | German | Greek | Japanese | Korean | Russian | T-Chinese top
NJF