Python 2.7:用汉字读取文件

Python 2.7:用汉字读取文件,python,unicode,encoding,character,filenames,Python,Unicode,Encoding,Character,Filenames,我正在尝试分析CSV文件中的数据,这些文件的名称中包含中文字符(例如。“粗1 25g”)。 我使用Tkinter选择如下文件: selectedFiles = askopenfilenames(filetypes=[("xlsx","*"),("xls","*")]) # Utilize Tkinker dialog window to choose files selectedFiles = master.tk.splitlist(selectedFiles) # Create list fr

我正在尝试分析CSV文件中的数据,这些文件的名称中包含中文字符(例如。“粗1 25g”)。 我使用Tkinter选择如下文件:

selectedFiles = askopenfilenames(filetypes=[("xlsx","*"),("xls","*")]) # Utilize Tkinker dialog window to choose files
selectedFiles = master.tk.splitlist(selectedFiles) # Create list from files chosen
我尝试通过以下方式将文件名转换为unicode:

selectedFiles = [x.decode("utf-8") for x in selectedFiles]
只会产生错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xb4 in position 0: ordinal not in range(128)
IOError: [Errno 22] invalid mode ('wb') or filename: 'C:\...\\data_division_files\\\xe7\xb2\x971 25g.csv'
我还尝试了转换文件名,因为文件是使用以下内容创建的:

titles = [x.encode('utf-8') for x in titles]
仅接收错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xb4 in position 0: ordinal not in range(128)
IOError: [Errno 22] invalid mode ('wb') or filename: 'C:\...\\data_division_files\\\xe7\xb2\x971 25g.csv'
我也尝试过上述方法的组合,但没有效果。 我可以做些什么来允许用Python读取这些文件


(这个问题虽然相关,但无法解决我的问题:)

当您在
unicode
对象上调用
decode
时,它首先使用
sys.getdefaultencoding()
对其进行编码,以便它可以为您解码。这就是为什么即使您没有在任何地方要求ASCII,您也会得到一个关于ASCII的错误

那么,从哪里获得
unicode
对象呢?从
askopenfilename
。从快速测试来看,它似乎总是在Windows上返回
unicode
值(可能是通过获取UTF-16并对其进行解码),而在POSIX上,它返回一些
unicode
和一些
str
(我猜,不必考虑任何适合7位ASCII的内容,而是使用文件系统编码对其他内容进行解码)。如果您尝试打印repr或type或任何
selectedFiles
,问题将显而易见


同时,
encode('utf-8')
不应导致任何
UnicodeError
s…但您的文件系统编码在Windows上可能不是utf-8,因此它可能会导致大量的
IOError
s,错误号为2(尝试打开不存在的文件,或在不存在的目录中创建文件),21(试图在Windows上打开具有非法文件名或目录名的文件),等等。看起来这正是您看到的。实际上没有理由这样做;只需将路径名原样传递到
open
即可


因此,基本上,如果您删除了所有的
encode
decode
调用,那么您的代码可能会正常工作


然而,还有一个更简单的解决方案:只需使用
askopenfile
asksaveasfile
而不是
askopenfilename
asksaveasfilename
。让Tk了解如何使用其路径名,并将文件对象交给您,而不是自己搞乱路径名。

您必须知道,哪种编码是正确的用于文件名。根据错误消息判断,可能是utf16。请尝试文件名。解码(“utf16”)导入编解码器,然后对中文文件名文本使用正确的编解码器方法。导入codecs@NileshG:
codecs
用于Unicode内容;它对Unicode文件名没有任何好处。@阿巴内特:文件名只是一个文本…所以我们可以使用codecs…我认为问题首先在于文件的命名。如果我更改我选择的文件列表中的元素,则这些文件不存在。我必须确保原始文件名可被askopenfilenames函数和我正在对其执行的其他函数读取。当我在使用
decode('utf-8')
后打印所选文件时,我得到
[u'C:/…/data\u division\u files/\u7c973 25g.csv']
。当我使用
utf-16
时,我遇到了一个新错误:
UnicodeDecodeError:“utf16”编解码器无法解码第54位的字节0x76:截断的数据
,选择的文件显示为
('C:/…/data\u division\u files/\xe5\x8e\x9f\xe6\xa0\xb7 25g.csv')
。没有任何编码/解码,代码就无法正常工作,askopenfiles会出现一个新错误:
IOError:[Errno 2]没有这样的文件或目录:u'{'
@nichosukiennik:我想让你打印出
所选文件
,而不做任何修改,就像
askopenfilename
返回的一样。@nichosukiennik:同时,如果
askopenfile
不起作用,也许问题是Python猜测你的文件系统编码错误(或者,更糟糕的是,您的文件系统没有一致的编码。)
sys.getfilesystemencoding()
怎么说?
sys.getfilesystemencoding()
一开始给了我
cp936
,下一次我尝试给我
mbcs
。选择文件而不做任何事情给了我
文件“C:\Python27\lib\site packages\numpy\lib\\u datasource.py”,第479行,在open raise IOError(“%s未找到”。%path)IOError:C:/Users/nsukiennik/data\u division\u files/粗2 25g.csv未找到。Tkinter回调中出现异常
。那么Tkinter可能有问题吗?@nichosukiennik:Wow,听起来你的设置很奇怪。如果Python无法确定它从文件系统返回的字符集是什么,唯一的选择就是手动执行,这很痛苦。(python的更高版本更多地使用Windows UTF-16 API,较少使用OEM代码页API,但是(a)您可能无法升级到3.x,以及(b)我不知道tkinter是否已经更新。无论如何,有两个选项: