wxPython(Phoenix) FileDialogのパスは正規化したほうがいいよ

環境

  • mac os version: 10.11.5
  • wxPython(Phoenix) version: 3.0.3.dev2749+f803d20 osx-cocoa (phoenix)

本文

wxPythonにてFileDialogを使った、ファイルのオープンにおいて、 日本語ファイルの存在を確認したい場面があった。 というか、絶対に存在するはずなのに、見つからない問題に遭遇した。 以下簡単な例

# 不十分な例。そのままインタプリタにコピペできます。
import os
import wx

# 本当は、第一引数はwx.Frameとかにすべき
openFileDialog = wx.FileDialog(None, "Open a file", "", "",
        "*.*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

if openFileDialog.ShowModal() == wx.ID_CANCEL:
    print('キャンセルされたよ')
    exit()

# 選択されたファイルのパスを取得
path = openFileDialog.GetPath()
dirname = os.path.dirname(path)
for i in os.scandir(dirname):
# 選択されたファイルの親を走査するので、必ず、選択されたファイルはあるはず。
    if i.path == path:
        print('一致するやつがあったよ。')
        break
else:
    print('一致するのがなかったよ。おかしいよ。')

これは必ず一致するように書いているつもりだが、

ダクテン.txt

を選択すると、一致するのがなかったよ。おかしいよ。と言われる。

最初にこの問題に遭遇した時は、何が原因かさっぱりだった。 日本語がそもそも無理なのかと思ったが、ハロー.txtはきっちり一致する。

encodeしたりdecodeしているうちに気付いた。 ダクテン.txtなのにが1文字分を占めていることに。 これをもとに調べてみると、

6.5. unicodedata — Unicode データベース — Python 3.5.2 ドキュメント

このようなモジュールがあるようだ。Python素敵。この中のnormalizeを用いれば良い。

# 改良したもの。そのままインタプリタにコピペできます。
import os
import wx
import unicodedata

# 本当は、第一引数はwx.Frameとかにすべき
openFileDialog = wx.FileDialog(None, "Open a file", "", "",
        "*.*", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

if openFileDialog.ShowModal() == wx.ID_CANCEL:
    print('キャンセルされたよ')
    exit()

path = openFileDialog.GetPath()
dirname = os.path.dirname(path)
np = unicodedata.normalize('NFC', path)
for i in os.scandir(dirname):
# 今度は必ず、breakできる
    if unicodedata.normalize('NFC', i.path) == np:
        print('一致するやつがあったよ。')
        break
else:
    print('一致するのがなかったよ。おかしいよ。')

normalizeが雑だが、こうすれば、ダクテン.txtでも一致する

本当は、まだ、カバー仕切れてないのがあるかもと少し不安。

タイトルとURLをコピーしました