【问题标题】:Reading Japanese filenames in windows, using Python and glob not working在 Windows 中读取日文文件名,使用 Python 和 glob 不起作用
【发布时间】:2011-03-05 21:35:43
【问题描述】:

我刚刚在我的系统上设置了 PortablePython,所以我可以从 PHP 运行 python 脚本,并且我得到了一些非常基本的代码(如下)来列出目录中的所有文件,但是它不适用于日文文件名。它适用于英文文件名,但是当我将任何包含日文字符的文件放在目录中时,它会吐出错误(如下)。

import os, glob

path = 'G:\path'
for infile in glob.glob( os.path.join(path, '*') ):
    print("current file is: ", infile)

使用 'PyScripter-Portable.exe' 可以正常工作,但是当我尝试在命令提示符或 PHP 中运行 'PortablePython\App\python.exe "test.py"' 时,会出现以下错误:

current file is:  Traceback (most recent call last):
  File "test.py", line 5, in <module>
    print("current file is: ", infile)
  File "PortablePython\App\lib\io.py", line 1494, in write
    b = encoder.encode(s)
  File "PortablePython\App\lib\encodings\cp437.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 37-40: character maps to <undefined>



我对 Python 很陌生,只是用它来解决 PHP 问题,无法在 Windows 中读取 unicode 文件名......所以我真的需要这个工作 - 你能给我的任何帮助都会很棒。

【问题讨论】:

  • 请阅读您的回溯并注意glob 有效,但print 无效!

标签: python windows unicode directory


【解决方案1】:

问题可能是您打印到的任何输出目标都没有使用与文件系统相同的编码。一般规则是您应该尽快将文本转换为 Unicode,然后在输出时转换为您需要的任何字节编码(例如 utf-8)。

由于您正在处理文件名,它们应该在系统编码中。

import sys
fse = sys.getfilesystemencoding()
filenames = [unicode(x, fse) for x in glob.glob( os.path.join(path, '*') )]

现在您所有的文件名都是 Unicode,您需要找出正确的编码以从命令提示符或其他输出(您可以使用 u 标志启动 Unicode 版本的命令提示符:“cmd /u”)

【讨论】:

  • 这对我不起作用(我使用的是 3.0 顺便说一句)。提示?此外, cmd /u 仍然会吐出相同的错误。
  • 我得到TypeError: decoding Unicode is not supported 2.7
【解决方案2】:

假设您使用的是 python 2.x,请尝试将字符串更改为 unicode,如下所示:

path = u'G:\path'
for infile in glob.glob( os.path.join(path, u'*') ):
    print( u"current file is: ", infile)

这应该让 python 的文件系统相关函数知道你想要使用 unicode 文件名。

【讨论】:

  • 嗯...也许不是。 Python 3.0 已经将 unicode 用于其字符串。
  • 出于好奇,当你用这个替换你的打印语句时会发生什么? print( infile.encode('utf8'))
  • 它实际上可以工作,哈哈,但返回转义字符或其他任何字符(\x8f\xe3\x81\x97 - 等)......这是一个愚蠢的问题,因为我发誓我以前用过这些,但我如何解码这些?主要是PHP。我 - 知道 - 有一个功能,但我想不出要搜索什么才能再次找到它。顺便说一句,这很有帮助。
  • 更新:所以我尝试使用 utf8_decode 但它不起作用......然后我尝试将它粘贴到双引号中的打印语句中 - 它会解码字符串。对解码所有内容没有帮助,但它确实让我开心。知道执行此操作的函数吗?
  • 最后更新:感谢 php.net 的 utf8_decode 评论部分的 Johan K,我已经修复了它。如果有人想知道我只需要使用以下代码:
    $return = preg_replace("#(\\\x[0-9A-Fa-f]{2})#e", "chr( hexdec('\\1'))", $return);
【解决方案3】:

加载路径中带有 unicode 符号的文件示例:

from glob import glob
import librosa

#File has chanies in path

#Find all wav-s
replays_files = glob('<you-path>/**/*.wav', recursive=True)

s = replays_files[1478]
#Will be something like this:
#'<you-path>\udde6\uabae\udc9a\udce4_audio.wav'


#If you try load
librosa.core.load(s,sr=16000,mono=True)
#UnicodeEncodeError: 'ascii' codec can't encode characters in position 222-242: ordinal not in range(128)

#Replace udde6\ 
s = s.encode('ascii','surrogateescape').decode()

#Still doesn't working
librosa.core.load(s,sr=16000,mono=True)
#UnicodeEncodeError: 'ascii' codec can't encode characters in position 222-228: ordinal not in range(128)

s = s.encode('utf-8')
#b'<you-path>\xe6\xbe\x7a\xe4\xb8_audio.was'

#Work
librosa.core.load(s,sr=16000,mono=True)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-28
    • 2014-11-17
    • 2013-04-04
    • 2020-12-09
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多