14

ファイルを移動する必要があるスクリプトを書いていますが、残念ながらos.path、国際化にうまく対応していないようです。ヘブライ語で名前が付けられたファイルがあると、問題が発生します。ディレクトリの内容のスクリーンショットを次に示します。

代替テキスト
(ソース: thegreenplace.net )

ここで、このディレクトリ内のファイルを処理する次のコードを検討してください。

files = os.listdir('test_source')

for f in files:
    pf = os.path.join('test_source', f)
    print pf, os.path.exists(pf)

出力は次のとおりです。

test_source\ex True
test_source\joe True
test_source\mie.txt True
test_source\__()'''.txt True
test_source\????.txt False

os.path.existsヘブライ語で名前が付けられたファイルが存在しないと考える方法に注意してください。どうすればこれを修正できますか?

Windows XP Home SP2 上の ActivePython 2.5.2

4

4 に答える 4

17

うーん、掘り下げた後、os.listdirにユニコード文字列を指定すると、次のように機能するようです。

files = os.listdir(u'test_source')

for f in files:

    pf = os.path.join(u'test_source', f)
    print pf.encode('ascii', 'replace'), os.path.exists(pf)

===>

test_source\ex True
test_source\joe True
test_source\mie.txt True
test_source\__()'''.txt True
test_source\????.txt True

ここでいくつかの重要な観察事項:

  • Windows XP (すべての NT 派生製品と同様) は、すべてのファイル名を Unicode で保存します。
  • os.listdir(および のような同様の関数os.walk) は、Unicode パスで正しく機能するために、Unicode 文字列を渡す必要があります。前述のリンクからの引用は次のとおりです。

ファイル名を返す os.listdir() は問題を引き起こします: ファイル名の Unicode バージョンを返す必要がありますか、それともエンコードされたバージョンを含む 8 ビット文字列を返す必要がありますか? os.listdir() は、ディレクトリ パスを 8 ビット文字列または Unicode 文字列のどちらで指定したかに応じて、両方を実行します。Unicode 文字列をパスとして渡すと、ファイル システムのエンコーディングを使用してファイル名がデコードされ、Unicode 文字列のリストが返されます。一方、8 ビット パスを渡すと、ファイル名の 8 ビット バージョンが返されます。

  • 最後に、printUnicode ではなく ascii 文字列が必要なため、パスを ascii にエンコードする必要があります。
于 2009-01-30T21:40:06.730 に答える
3

Unicode と ASCII の問題のように見えます - os.listdirASCII 文字列のリストを返しています。

編集: Python 3.0 と XP SP2 で試してみましたがos.listdir、ヘブライ語のファイル名をリストする代わりに単純に省略しました。

ドキュメントによると、これはデコードできなかったことを意味します。

os.listdir() が文字列のリストを返す場合、正しくデコードできないファイル名は UnicodeError を発生させるのではなく省略されることに注意してください。

于 2009-01-30T21:25:24.513 に答える
1

OS XでPython 2.5.1を使用すると、魅力的に機能します。

subdir/bar.txt True
subdir/foo.txt True
subdir/עִבְרִית.txt True

ひょっとして、これは Windows XP と何らかの関係があるということでしょうか?

編集:Windowsの動作をよりよく模倣するために、Unicode文字列も試しました:

for f in os.listdir(u'subdir'):
  pf = os.path.join(u'subdir', f)
  print pf, os.path.exists(pf)

subdir/bar.txt True
subdir/foo.txt True
subdir/עִבְרִית.txt True

ターミナル (os x ストック コマンド プロンプト アプリ) で、つまり。IDLE を使用しても機能しましたが、ファイル名が正しく出力されませんでした。本当にユニコードであることを確認するために、次のことを確認しました。

>>>os.listdir(u'listdir')[2]
u'\u05e2\u05b4\u05d1\u05b0\u05e8\u05b4\u05d9\u05ea.txt'
于 2009-01-30T21:38:37.683 に答える
0

疑問符は、Unicode 文字を特定のエンコーディングで表現できない場合に表示される多かれ少なかれ普遍的な記号です。Windows での端末または対話セッションは、おそらく ASCII または ISO-8859-1 などを使用しています。したがって、実際の文字列はユニコードですが、???? に変換されます。端末に出力されたとき。そのため、OSX を使用して PEZ で動作します。

于 2009-01-30T22:27:12.577 に答える