ようこそ ゲスト さん、新規登録(無料)して気になる疑問を解決しませんか?

質問

QNo.4034599 Python の utf16le デコードが化ける。
質問者:finch_nk Python2.5で日本語を扱おうと試みています。
utf16le で書かれた "名" という文字を他の文字コードに変換しようとすると、なぜか"吊"に化けるという現象に悩んでいます。
他の文字ではこのような現象は見ていないのですが、何か使い方を間違っているのでしょうか?

ちなみに、コンソールでは例えばna.txt の内容が "名"1文字として、
import codecs
utf16_file = codecs.open('na.txt', 'r', 'utf_16_le')
print utf16_file.readline()

とすると"吊"が表示されてしまいます・・・。
どなたか原因に心当たりがあったら教えてください。m(_ _)m
困り度:
  • 困っています
質問投稿日時:
08/05/19 20:51
この質問に対する回答は締め切られました。

回答

ANo.4 わたしがWindowsで使っているのはPythonの配布元で配布しているものです。
ActivePythonを入れて試すというのはちょっとできないのでその辺は申し訳ないのですが、

sitecustmize.pyを

import sys
sys.setdefaultencoding('cp932')

にして以下のように動作しています

>python
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'cp932'
>>> def foo():
... import codecs
... uf = codecs.open('na.txt', 'r', 'utf-16le')
... return uf.readlines()
...
>>> foo()
[u'\u540d\u523a\r\n']
>>> print foo()[0]
名刺

ファイルから読み込んできた状態でどうなっているか確認してもらえますか?
とりあえず↑と同じ操作をやってもらえればOKです。
回答者:sakusaker7
種類:回答
どんな人:一般人
自信:参考意見
回答日時:
08/05/20 09:24
この回答へのお礼ご回答ありがとうございます。

結局ActivePythonのバージョンアップをしたら治ってしまいました・・・。
ただ、別環境では古いバージョンでも問題ないので、ActivePythonのせいではないはずです。やはり参考書などを見ながら何らかの設定をしてしまっていたのかも知れません。

どうもありがとうございました。

回答

ANo.3 ActivePythonは使ったことがないので微妙に違うかもしれませんが、

print utf16_file.readline()

print utf16_file.readline().encode('sjis')
としたらどうなりますか?

あるいは、
import sys
import os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

を実行してから試すと何か変化はありますか?
回答者:sakusaker7
種類:補足要求
どんな人:一般人
自信:参考意見
回答日時:
08/05/20 01:04
この回答への補足ご回答ありがとうございます。

print utf16_file.readline().encode('sjis')
としても、やはり"名"は化けました。

import sys
import os, msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
とすると、この段階で
16384
と表記され、その後は変化がありませんでした・・・。

ところで別のWindowsVistaのPCにActivePythonを入れて試したところ、
今度は問題なく動きました。
仕事で使っているのはXPの方なので、逆なら良かったのですが・・・。
この回答へのお礼この回答にお礼をつける(質問者のみ)

回答良回答20pt

ANo.2 動作環境はどういったものでしょうか?
それと対話環境で実行した場合、どこかで(スタートアップ時のコンフィグファイルとか)
エンコーディングを指定していないと

Python 2.5.1 (r251:54863, May 18 2007, 16:56:43)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import codecs
>>> utf16_file = codecs.open('na.txt', 'r', 'utf_16_le')
>>> print utf16_file.readline()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u540d' in position 0
: ordinal not in range(128)
>>> print utf16_file.readline().
File "<stdin>", line 1
print utf16_file.readline().
^
SyntaxError: invalid syntax

こんな風になると思うのですが。
で気がついたことが一つ。

>echo 吊名|nkf -S -w16|od -t x1
0000000 54 0a 54 0d 00 0d 00 0a
0000010

これはBigendianでの結果ですが、見ての通り'名'の 0x0aを
0x0dにすると'吊'です。
バイトストリームでCRLF変換ありで出力してたりしませんか?
回答者:sakusaker7
種類:補足要求
どんな人:一般人
自信:参考意見
回答日時:
08/05/19 23:00
この回答への補足早速ご回答ありがとうございます。

すみません。全くの初心者で
”バイトストリームでCRLF変換あり”という操作が分かりません・・・。
分かる限りでは、WindowsXP上でActivePython (2.5)を使っています。
設定の変更は、デフォルトのエンコードをsitecustomize.pyで
cp932に指定したのみだと思います。

サンプルのファイルとして、"名"一文字にしましたが、実際には
"紙に名前を書いた物が名刺である。"が
"紙に吊前を書いた物が吊刺である。"となってしまいます・・・。
この回答へのお礼どうもありがとうございます!
”バイトストリームをCRLF変換”がよく分からなかったのですが、色々調べてみた結果、どうやらそれが原因らしいことが分かりました。
(ほかにも文字コードの末尾?が0Dで終わる鰍やら倍が化けたのでそうだと思います。)

 その線で解決できそうです!
 どうもありがとうございました。

回答良回答10pt

ANo.1 Linux(Fedora8)のPython2.5.1だと問題なく処理できますね。
"名"が 540d で、"吊"が 540a なので、おそらく改行コードの問題でしょう。OSは何でしょうか?
回答者:notnot
種類:回答
どんな人:一般人
自信:参考意見
回答日時:
08/05/19 22:31
この回答への補足早速にご回答ありがとうございます。

WindowsXP上でActivePython (2.5)を使っています。
設定の変更は、デフォルトのエンコードをsitecustomize.pyで
cp932に指定したのみだと思います。

文中でも化け、しかも他の文字には全く影響を与えません。
改行コードについて、いろいろ変えて試してみようと思います。
ありがとうございます。
この回答へのお礼どうもありがとうございました。
やはり改行コードの問題だったようです。
(ようです、というのは、ActivePythonのバージョンアップを兼ねて再インストールしたら治ってしまったのです・・・。多分、自分でなんか変な設定をして忘れていたのだと思います。お騒がせいたしました。)

改行コード?ということで、ほかの化ける文字を探していたら、似たような
文字コードのばかり(0Dで終わる)だったので、やはり改行コードを変換する過程でこれもいじっていたようです。

 どうもありがとうございました。