【问题标题】:Printing file names with unicode characters in Python 2.7在 Python 2.7 中使用 unicode 字符打印文件名
【发布时间】:2023-03-06 15:57:01
【问题描述】:

我有一个程序可以帮助处理一些文件操作任务。它会像这样构建要使用的文件列表:

useful_files = [file for file in os.listdir(self.operatingDirs[0])
                if re.match(this_task_re, file)]

然后它会处理它们。它不时地告诉用户它在做什么:

for file_name in useful_files:
    pub.sendMessage("LOG MESSAGE", msg = "Checking folders for %s" % file_name)

当欧洲用户使用这个程序时,它开始像这样失败:

File "usefulfilefolder.pyc", line 310, in _DeduceDropBoxFolders UnicodeDecodeError: 'ascii' codec can't decode byte 0xcc in position 14: ordinal not in range(128)

sendMessage 通话在线。

错误似乎是由于我试图将我从os.listdirs 获得的文件名插入到消息字符串中而产生的。

IE:我从文件系统得到的文件名好像不能直接打印回来。

这对吗?

我该如何处理?

请注意,我必须(我相信)保留从 listdirs 获得的名称,以便我可以在其他文件系统操作中使用它来引用同一文件....

谢谢!

(注意 - 由于不支持的库,我目前无法轻松升级到 Python3)

(已编辑以阐明以下 cmets 中提出的观点)

【问题讨论】:

  • 你能给出你的sendMessage方法的代码吗?我认为您正在执行某种类型的编码(例如 message.encode('utf-8')),期望接收 ASCII。
  • decode 错误通常表明您正在尝试在某处组合 unicode 和字符串值;你能告诉我们完整的追溯吗?
  • 我详细说明了回溯:回溯中的最后一行指向其中包含 sendMessage 调用的行。我认为这意味着我在这个 % 语句中将 unicode 与字符串结合起来。我该如何避免这样做 - 我从操作系统调用中获得了 file_name。我需要(我相信)保持原样,以便以后可以使用它来访问文件。每当我去打印它时,我是否需要以某种方式处理它,比如 msg = "blah %s" % sanitize(file_name) ?
  • 我认为引用的代码/错误/行不准确。您有一个字节字符串文件名(顺便说一句,这是一个糟糕的开始 - 在 Windows 上使用 unicode 字符串作为文件名,否则您将无法访问语言环境代码页之外的任何内容),根据您隐式解码的错误,统一码。但是sendMessage 调用引用的行只有字节字符串,因此不能产生UnicodeDecodeError(尽管sendMessage 本身的实现可能)。 sendMessage 是什么——它应该支持 Unicode 参数吗?
  • 我开始认为由于某种原因回溯也被截断了。我已经确定 os.listdir 返回的文件名是 strs,而不是 unicodes。当文件名中包含非 ascii 字符时,有些东西无法解码这个 str。 sendMessage 来自 pubsub 库。我开始认为,实际错误正在发生的消息的接收者中,或者甚至更有可能是在其中......

标签: python-2.7 unicode


【解决方案1】:

首先,使您的文件具有正确的编码,例如 utf-8。 http://www.python.org/dev/peps/pep-0263/

然后,在出现错误的地方使用 some_string.decode('the encoding')。

【讨论】:

  • 除非我弄错了,否则这个答案意味着您认为我正在从文件中读取?我没有从文件中读取 - 我从 os.listdir 获取名称,并尝试将其插入字符串。这就是事情失败的地方。
【解决方案2】:

我发现如果我做这种事情:

file_name =  os.listdir(problem_dir)[0]
print "I looked at %s" % file_name

我收到 unicode 错误。这真的是yuk吗?在我看来是:我无法安全地打印从 os.listdir() 获得的东西!

如果我这样做:

file_name =  os.listdir(problem_dir)[0]
print "I looked at %s" % file_name.decode(sys.getfilesystemencoding())

然后就可以了。

所以这是某种答案,但我真的希望有更好的方法吗?

我发现很难测试,因为我的机器上没有 unicode 文件名,所以我一直不得不与合作用户进行迭代。我想知道:这样做是否有效

file_name =  os.listdir(problem_dir)[0].decode(sys.getfilesystemencoding())

然后在任何地方都使用该名称。我能相信这个事实吗

os.path.exists(file_name) 在进行解码后会是真的吗? (如果是真的就好了,但会让我吃惊)

TVMIA!

【讨论】:

  • 我意识到这个“答案”在我认为正在发生的一件事上是错误的:我根本没有 unicode 文件名,我有字节字符串的文件名,可能不是 ascii ,这就是 os.listdir 返回的内容,这就是为什么我必须使用 sys.getfilesystemencoding() 对它们进行解码。否则其他东西会尝试将它们解码为 ascii....
【解决方案3】:

结果证明,最好的解决方案是:

from __future__ import unicode_literals

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 2013-08-29
    • 2016-12-03
    • 2012-06-27
    • 1970-01-01
    • 2016-05-29
    相关资源
    最近更新 更多