listdir无法正确显示非英文字母

4
在Python2.7中,
for dir in os.listdir("E:/Library/Documents/Old - Archives/Case"):
   print dir

打印输出:

Danny.xlsx
Dannyh.xlsx
~$??? ?? ?????? ??? ???? ???????.docx

当这样时:

# using a unicode literal
for dir in os.listdir(u"E:/Library/Documents/Old - Archives/Case"):
   print dir

输出:

Dan.xlsx
Dann.xlsx

Traceback (most recent call last):
  File "E:\...\FirstModule.py", line 31, in <module>
    print dir
  File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 2-4: character maps to <undefined>

文件名是希伯来语,如下所示:המסמך.xls。我该如何在Python中以希伯来语显示它?

更多的奇怪现象:s = os.listdir(u"E:/Library/Documents/Old - Archives/Case")[2] print s 完全正常。 - mirandalol
解决了:在文档顶部添加# -*- coding: utf-8 -*-解决了这个问题。 - mirandalol
2
当你解决了自己的问题时,应该将答案作为答案而不是评论发布,并接受它。 - agf
1
@Saga 这毫无意义。声明源编码如何影响I/O呢? - tchrist
3个回答

6
使用 u'' 字符串字面量的版本可以正常工作:使用 Unicode 路径名进行询问,将得到一个 Unicode 路径名作为响应,使您能够使用包含当前代码页之外字符的文件名。

你的问题仅来自尝试 print 文件名。在 Windows 命令提示符中获取 Unicode 输出是一项艰巨的任务。

默认的 C 标准库打印函数受限于区域设置代码页。除非直接调用 Win32 API 函数 WriteConsoleW(使用 ctypes),否则您永远不会获得可靠的控制台 Unicode 支持;即使这样,除非选择了适当的非默认字体,否则它也无法工作。这影响几乎所有非本地命令行工具,而不仅仅是 Python。


这正是我一直在寻找的!我读取了文件夹名称,但不知道Python给我的编码方式。我必须猜测多个编解码器名称才能将Unicode代码点值提取出来。这真的解决了问题。 - off99555
事实上,Python 没有为我推断任何编码。它只是以十六进制值的形式给了我字节,并让我自己找到这些文件名的编码。 - off99555

2
我已经解决了它:在文档顶部加上# -*- coding: utf-8 -*-就可以解决这个问题。

这并不能解决所描述的问题。同时还必须有其他变化发生。该注释仅声明源编码,并且仅影响Python 2中具有非ASCII字符的源文件。此示例仅为ASCII,因此不会产生任何影响。更有可能的是,OP在同时将listdir更改为Unicode字符串。 - Mark Tolonen

1
问题在于您的输出控制台使用了cp1252编码,根据错误消息,希伯来语无法在该编码下打印。请使用支持UTF-8的IDE,并在该IDE中使用支持希伯来语的字体,这样在使用具有Unicode路径的os.listdir时,它将正常工作。
以下是来自PythonWin IDE的示例,其中包括使用Unicode路径和不使用Unicode路径的情况。
PythonWin 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32.
Portions Copyright 1994-2008 Mark Hammond - see 'Help/About PythonWin' for further copyright information.
>>> import os
>>> for f in os.listdir('.'):
...     print f
...     
x.exe
x.py
x.pyc
y.py
?????.xls
>>> for f in os.listdir(u'.'):
...     print f
...     
x.exe
x.py
x.pyc
y.py
המסמך.xls

请注意,源文件中的编码声明对生成输出没有任何作用。它仅声明了源文件保存的编码方式,这会影响在源文件中编写非ASCII字符的能力。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接