通过Python脚本在Windows XP上创建的文件名中的编码错误

时间:2012-10-23 13:36:45

标签: python windows unicode encoding utf-8

我的Python脚本在Windows XP下创建了一个xml文件,但该文件没有使用西班牙语字符(如“ñ”或某些重音字母)进行正确的编码。

首先,使用以下代码从excel shell读取文件名,我用来读取Excel文件xlrd库:

filename = excelsheet.cell_value(rowx=first_row, colx=5)

然后,我尝试了一些没有成功的编码来生成具有正确编码的文件:

filename = filename[:-1].encode("utf-8")
filename = filename[:-1].encode("latin1")
filename = filename[:-1].encode("windows-1252")

使用“windows-1252”我的编码错误,字母'ñ','í'和'é'。例如,我得到了BAJOARAGÓN_Alcañiz.xml 而不是BAJOARAGÓN_Alcañiz.xml

提前感谢您的帮助

4 个答案:

答案 0 :(得分:1)

您应该为文件名使用unicode字符串。通常,操作系统支持包含任意Unicode字符的文件名。所以如果你这样做:

fn = u'ma\u00d1o'  # maÑo
f = open(fn, "w")
f.close()
f = open(fn, "r")
f.close()

它应该工作得很好。当您列出该文件所在目录的内容时,您在终端中看到的是另一回事。如果终端的编码是UTF-8,你会看到文件名maño,但如果编码是例如iso-8859-1,你会看到maÃo。但即使你看到这些奇怪的字符,你也应该能够如上所述从python打开文件。

总之,不要对

的输出进行编码
filename = excelsheet.cell_value(rowx=first_row, colx=5)

而是确保它是一个unicode字符串。

阅读the Python Unicode HOWTO Unicode文件名部分对您有所帮助。

答案 1 :(得分:1)

尝试你的答案我找到了一个快速的解决方案,从Python 2.7和Python 3.3移植我的脚本,移植我的代码的原因是Python 3在Unicode中默认工作。

我必须对我的代码做一些小改动,导入xlrd库(以前我必须安装xlrd3):

import xlrd3 as xlrd

另外,我必须使用str而不是encode()

将内容从'bytes'转换为'string'
filename = str(filename[:-1])

现在,我的脚本非常完美,可以在Windows XP上生成没有奇怪字符的文件。

答案 2 :(得分:0)

首先, 如果您还没有,请阅读http://www.joelonsoftware.com/articles/Unicode.html -

现在,“latin-1”应该适用于Windows下的西班牙语编码 - 有两种假设:您尝试“编码”到任一编码的strigns不是Unicdoe字符串,但已经在某种编码中。然而,tha可能会比奇怪的字符更容易给你一个UnicodeDecodeError,但它可能会在一些极端情况下起作用。

更可能的情况是您使用Windows Prompt AKA'CMD'检查您的文件 - 好吧,出于某种原因,Microsoft Windows确实使用两个不同的系统编码 - 一个来自“本机”Windows程序 - 它应该与latin1兼容,另一个用于传统DOS程序,其中它放置命令提示符的类别。对于葡萄牙语,这第二个编码是“cp852”(环顾四周,cp852没有定义“ñ” - 但cp850确实如此)。

所以,这发生了:

>>> print u"Aña".encode("latin1").decode("cp850")
A±a
>>> 

因此,如果您希望从DOS提示符中正确显示文件名,则应使用“CP850”对其进行编码 - 如果您希望它们从Windows程序中看起来正确,请使用“cp1252”(或“latin1”)对其进行编码或“iso-8859-15” - 它们几乎相同,给予或采取“€”符号)

当然,如果有人在挪威,俄罗斯或者Posix系统中运行你的程序,而不是试图猜测并挑选一个看起来不错的,并且会失败,你应该这样做

import sys
encoding = sys.getfilesystemencoding()

(这应该为你返回上面的一个 - 再次,如果从Windows程序看起来,文件名看起来是正确的,而不是来自DOS shell)

答案 3 :(得分:0)

在Windows中,文件系统使用UTF-16,因此不需要显式编码。只需使用Unicode字符串作为文件名,并确保声明源文件的编码

# coding: utf8
with open(u'BAJO ARAGÓN_Alcañiz.xml','w') as f:
    f.write('test')

此外,即使我的美国Windows系统的Ó编码不支持cp437,我的控制台 font 也支持该字符,它仍然在我的控制台上正确显示。控制台支持Unicode,但非Unicode程序只能读/写代码页字符。