[python] 日本語を含むPATHはいろいろと面倒だ と言う話

subprocessで日本語ありのパスのファイルを実行しようとすると、上手くいかなくてかなり苦戦したので
改めてPythonの日本語を使用するときの注意点とかについて。

やろうとしたのは

こんな感じで、exeの引数として日本語のパスを渡して標準出力をGETしたい…と言うことだったのですが
u””にしてもどうも上手くいかない。
それならばと u”” ではなく “” のstr 型にすればいけるんじゃね?とやってみたけれども
それもNG。
Python3.6ではPopenの引数としてエンコード設定があるようなのですが、2.7ではそれもなし。
さてどうしたものかとしばらく調べていたら str型にするにしても WINDOWSの場合は shift-jis(cp932) で
エンコードしていないと、日本語を含む文字はNGになってしまう と言うことが判明しました。
windowsの関係しない場合は、unicodeとstrが混在しないように気をつけていれば良いのですが、
windowsに対してコマンドを実行する場合や、フォルダの下のファイルを取得するglobのようなモジュールを
使用する場合は、渡す値や取得する値は、最終的にはshift-jis(cp932)のstrなので、
それをutf-8なstrやunicodeで扱うとUnicodeErrorになってしまいます。

私の場合、ファイルはutf-8で書いているのでファイルと、コマンドで取得する文字コードが違うものになってしまっているため
望まない形になっていたというわけですね。

pythonの場合、 type(moji) としたときで取得できる型が str であっても、
cp932なstrだったり、utf-8なstrだったりと、すべてが同じ文字コードとは限らないわけですが
そのおかげで 実は違うstrだったものを+したりしてしまってErrorになってしまうので
なにで取得して、どう使うのか意識しつつ
日本WINのパスはcp932で扱ってあげるとOKというわけですね。

上の例の場合

こうすればいけました。

さらなるトラップ

この場合、globはutf-8のunicodeを引数にしているためか帰ってくる値もunicodeになります。
ですが、

こうすると、ファイルは存在するのにファイルの一覧は取得できませんでした。
これは、utf-8なstrを引数にしているため
WINDOWSが文字を認識できずに取得できなかったためです。
なので、

まぁまずこんな書き方しねーよwwwっていう気もしますが、
日本語ありのstrでglobを使う時はcp932にしないとNGという話ですね。

・# coding: utf-8 の場合は、ファイル内で u”” にすると、utf-8になる
・Windowsはcp932で解釈される

なので、Twitterでも指摘があったとおり
・Windowsから取得するstrならば unicode(val,’cp932′) で、unicodeに変換してあげる
・strであわせるなら str(utf-8) -> unicode -> str(cp932) のようにunicodeを介してcp932にあわせてあげる
すると、安全だよ という事でした

けっこうPythonさわってますが、今更知りました。やっぱり適当な解釈でなんとなく進めちゃだめですね(汗

cp932とは?

http://qiita.com/kasei-san/items/cfb993786153231e5413

shift-jisでもいいのかなと思っていましたが、shift-jisの独自実装で
shift-jisを使用するよりも、Windowsならcp932としておいたほうがより安全だよ と言うことらしい。

だいぶ理由がわかったので、すこしは…ほんのすこしは日本語あっても怖くなくなった気がします。
たぶん気がするだけ…└(┐Lε:)┘

コメントを残す

メールアドレスが公開されることはありません。

*