我正在尝试分析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)
我还尝试转换文件名,因为文件是使用以下内容创建的:
titles = [x.encode('utf-8') for x in titles]
仅收到错误:
IOError: [Errno 22] invalid mode ('wb') or filename: 'C:\...\\data_division_files\\\xe7\xb2\x971 25g.csv'
我也尝试过上述方法的组合无济于事。 我该怎么做才能在Python中读取这些文件?
(这个问题,虽然相关,但未能解决我的问题:Obtain File size with os.path.getsize() in Python 2.7.5)
答案 0 :(得分:0)
当您在decode
对象上调用unicode
时,它会首先使用sys.getdefaultencoding()
对其进行编码,以便它可以为您解码。这就是为什么你得到关于ASCII的错误,即使你没有在任何地方要求ASCII。
那么,你从哪里得到一个unicode
对象?来自askopenfilename
。从快速测试看,它总是在Windows上返回unicode
值(大概是通过获取UTF-16并对其进行解码),而在POSIX上它返回一些unicode
和一些str
(我猜测只留下任何适合7位ASCII的东西,用你的文件系统编码解码其他任何东西)。如果您尝试打印出repr或类型或selectedFiles
的任何内容,问题就会很明显。
同时,encode('utf-8')
不应该导致任何UnicodeError
...但是你的文件系统编码可能不是Windows上的UTF-8,所以它可能会导致很多{{1}使用errno 2(尝试打开不存在的文件,或者在不存在的目录中创建文件),21(尝试在Windows上打开包含非法文件或目录名称的文件)等等。看起来就像你所看到的那样。并且没有理由这样做;只需按原样将路径名传递给IOError
,它们就可以了。
所以,基本上,如果您删除了所有open
和encode
来电,那么您的代码可能会正常工作。
但是,有一个更简单的解决方案:只需使用decode
或askopenfile
代替asksaveasfile
或askopenfilename
。让Tk弄清楚如何使用它的路径名,只需将文件对象交给你,而不是自己弄乱路径名。