Python 2.7:读取带有中文字符的文件

时间:2013-10-18 07:47:20

标签: 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 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

1 个答案:

答案 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,它们就可以了。


所以,基本上,如果您删除了所有openencode来电,那么您的代码可能会正常工作。

但是,有一个更简单的解决方案:只需使用decodeaskopenfile代替asksaveasfileaskopenfilename。让Tk弄清楚如何使用它的路径名,只需将文件对象交给你,而不是自己弄乱路径名。