年をまたいで、Pythonいじって遊んでいたのですが、どうもPython3.0でのMacOSXにおけるバグっぽいものを見つけてしまったようなので、メモ程度に。
fileを読み込むときのデフォルトのコーデックが、なぜかshift_jisになってしまっているようです。 ちなみに、XPだと普通に動きますし、MacでもファイルをShift_jisで保存すればそのまま動きます。 makeで入れたpythonですが、OSは10.4でも10.5でも同じでした。 Python 3.0 (r30:67503, Jan 1 2009, 00:12:01) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> f = open('temp.txt') >>> f.readline() Traceback (most recent call last): File " File "/Library/Frameworks/Python.framework/Versions/3.0/lib/python3.0/io.py", line 1813, in readline while self._read_chunk(): File "/Library/Frameworks/Python.framework/Versions/3.0/lib/python3.0/io.py", line 1562, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/Library/Frameworks/Python.framework/Versions/3.0/lib/python3.0/io.py", line 1295, in decode output = self.decoder.decode(input, final=final) UnicodeDecodeError: 'shift_jis' codec can't decode bytes in position 8-9: illegal multibyte sequence >>> >>> f.close() >>> f = open('temp.txt',encoding='utf=8') >>> f.readline() 'あいうえお\n' >>> f.close(); temp.txtは、UTF-8で保存されており、これをShift_jisにすると読めるので、おそらく組み込み関数openのデフォルトのencodingが、なぜかshift_jisになっていることが問題かと思われます。 本家のバグレポートには、それっぽいエントリーはなかったのですが、報告するにはまだ調べが足りないかな。。。 まあ、まだ3.0なので、次のバージョンでこっそり直っていてくれると嬉しいですが。 2009/1/4訂正 Windowsでは動くと書きましたが、どうやら勘違い。 やはり、Vista(SP1)とXP(SP3)ともに、デフォルトのfile読込時のcodecがcp932になっているようです。 仕方ないので、組み込み関数openのソースを見てみました。 io.pyのopen関数の中でTextIOWrapperを呼んでいるのですが、ここに出てくる os.device_encoding() が、どうやらいけないのかな? 3.0から導入されたメソッドっぽいですが、File Descriptorの番号に応じてencodingを返すようです。 ユーザーがファイルを開くと、3から順に番号が付けられると思うのですが、そのときは、encodingは返ってこないので、その下の、 encoding = locale.getpreferredencoding() が、結局呼ばれる事になります。 class TextIOWrapper(TextIOBase): _CHUNK_SIZE = 128 def __init__(self, buffer, encoding=None, errors=None, newline=None,line_buffering=False): if newline not in (None, "", "\n", "\r", "\r\n"): raise ValueError("illegal newline value: %r" % (newline,)) if encoding is None: try: encoding = os.device_encoding(buffer.fileno()) except (AttributeError, UnsupportedOperation): pass if encoding is None: try: import locale except ImportError: # Importing locale may fail if Python is being built encoding = "ascii" else: encoding = locale.getpreferredencoding() というわけで、これが、MacOSX10.4では、 >>> locale.getpreferredencoding() 'X-MAC-JAPANESE' となっていて、 >>> locale.getdefaultlocale() (None, 'X-MAC-JAPANESE') と、同じ。この名前が、Shift_JISにバインドされています。所謂、純粋なShift_JISで、Windows-31J(cp932)とは違います。 ちなみに、windowsXPでは、おなじメソッドが今度は、'cp932'を返すので、ファイルを開くときにcodecがおかしくなる理由が何となくわかりました。 Ubuntuだとすべて、UTF-8と返ってきて、問題まったくなし。んー、テストがLinuxで行われているのか? なんか、バグじゃなくて仕様のような気もしてきましたが、MacもWinも、できればデフォルトでUTF-8にして欲しいなー。 と思っていたら、やっぱり仕様でした。 ちゃんと、ドキュメントを読もう、という話です・・・ There is a platform-dependent default encoding, which on Unixy platforms can be set with the LANG environment variable (and sometimes also with some other platform-specific locale-related environment variables). What's new in Python3.0より。 なんと、環境ごとに気を遣ってくれているようです。(そんなんことしてくれなくていいのに・・・) というわけで、環境変数をいじります。 Macの場合、LANGは、Ja_JP.UTF-8になっているので、 __CF_USER_TEXT_ENCODING="0x1F5:0x08000100:14" export __CF_USER_TEXT_ENCODING とします。 __CF_USER_TEXT_ENCODINGの設定方法は、いまひとつ掴みきれていませんが、:で挟まれた二つ目の引数が、1になっているところを、UTF-8を表す、0x08000100に変更すると、ファイルのデフォルトcodecがUTF-8になります。 windowsは、だめですデフォルトのシステムロケールを変更できるのかどうかよくわかりません。 要調査。知っている人いたら教えてください。 スポンサーサイト
|
|
Pythonの3.0を試してみたら日本語表示でドモった。エンコーディングがutf-8のhoge.txtというファイルの中身を表示させてみる。環境はMacOSX(10.4.11)とPython3.0.1。 とりあえずやってみたら >>> fp = open("hoge.txt", "r") >>> h blankblankの日記【2009/03/04 00:42】
|
| ホーム |
|