Python 2.7 使用 "latin-1" 编码代替 "UTF-8"
Python 2.7 "latin-1" encoding used instead of "UTF-8"
我知道在 Python 2 上有很多关于 "UTF-8" 编码问题的讨论,但到目前为止我找不到解决问题的方法。我目前正在创建一个脚本来获取文件名并将其超链接到 xlwt 中,以便可以通过在电子表格中单击来访问该文件。问题是,这些文件的某些名称包含非 ASCII 字符。
问题一
我使用以下行来检索文件名。顺便说下文件夹里只有一个文件
>>f = filter(os.path.isfile, os.listdir(tmp_path))[0]
然后
>>print f
'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc'
>>print sys.stdout.encoding
'UTF-8'
>>f.decode("UTF-8")
*** UnicodeDecodeError: 'utf8' codec can't decode byte 0xe7 in position 76: invalid continuation byte
通过浏览此处的讨论,我意识到“\xe7\xe3o”不是 "UTF-8" 编码。 运行 下面这行似乎支持了这一点。
>>f.decode("latin-1")
u'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc'
那么我的问题是,为什么系统编码设置为"UTF-8"时变量f被编码为"latin-1"?
问题二
虽然 f.decode("latin-1") 给出了我想要的输出,但我仍然无法将变量提供给电子表格中的超链接函数。
>>data.append(["File", xlwt.Formula('HYPERLINK("%s";"%s")' % (os.path.join(dl_path,f.decode("latin-1")),f.decode("latin-1")))])
*** FormulaParseException: can't parse formula HYPERLINK("u'H:\Mad Lab\SE Doc Crawler\bovespa\download\521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc's;"u'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc's)
显然,右双引号被吃掉了,取而代之的是“'s”后缀。有人可以帮忙解释一下这里发生了什么吗? 0.0
哦,如果有人可以为上面的问题 2 提出解决方案,那么我将非常感激 - 因为你会让我的周末免于痛苦!
在此先感谢大家!
欢迎来到令人困惑的编码世界!至少要处理文件编码、终端编码和文件名编码,这三者可能不同。
在Python2.x中,目标是从一个编码的字符串中得到一个Unicode字符串(不同于str
)。问题是您并不总是知道用于 str
的编码,因此很难对其进行解码。
当使用 listdir()
获取文件名时,有一个已记录但经常被忽视的怪癖 - 如果您将 str
传递给 listdir()
,您将得到 str
的编码。这些将根据您的语言环境进行编码。在 Windows 上,这些将是一个 8 位字符集,如 windows-1252
。
或者,传递 listdir()
Unicode 字符串。
例如
os.listdir(u'C:\mydir')
注意 u
前缀
这将return 正确解码 Unicode 文件名。在 Windows 和 OS X 上,只要您的环境语言环境没有被弄乱,这是非常可靠的。
在你的情况下,listdir()
会 return:
u'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc'
再次注意 u
前缀。您现在可以将其打印到您的 PyCharm 控制台,无需修改。
例如
f = filter(os.path.isfile, os.listdir(tmp_path))[0]
print f
至于问题 2,由于时间限制,我没有进一步调查,只是将输出打印为 unicode 字符串,而不是 xlwt 对象。我能够继续这个项目,尽管不了解这里出了什么问题。从这个意义上说,上面的两个问题已经得到了回答。
我知道在 Python 2 上有很多关于 "UTF-8" 编码问题的讨论,但到目前为止我找不到解决问题的方法。我目前正在创建一个脚本来获取文件名并将其超链接到 xlwt 中,以便可以通过在电子表格中单击来访问该文件。问题是,这些文件的某些名称包含非 ASCII 字符。
问题一
我使用以下行来检索文件名。顺便说下文件夹里只有一个文件
>>f = filter(os.path.isfile, os.listdir(tmp_path))[0]
然后
>>print f
'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc'
>>print sys.stdout.encoding
'UTF-8'
>>f.decode("UTF-8")
*** UnicodeDecodeError: 'utf8' codec can't decode byte 0xe7 in position 76: invalid continuation byte
通过浏览此处的讨论,我意识到“\xe7\xe3o”不是 "UTF-8" 编码。 运行 下面这行似乎支持了这一点。
>>f.decode("latin-1")
u'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc'
那么我的问题是,为什么系统编码设置为"UTF-8"时变量f被编码为"latin-1"?
问题二
虽然 f.decode("latin-1") 给出了我想要的输出,但我仍然无法将变量提供给电子表格中的超链接函数。
>>data.append(["File", xlwt.Formula('HYPERLINK("%s";"%s")' % (os.path.join(dl_path,f.decode("latin-1")),f.decode("latin-1")))])
*** FormulaParseException: can't parse formula HYPERLINK("u'H:\Mad Lab\SE Doc Crawler\bovespa\download\521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc's;"u'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc's)
显然,右双引号被吃掉了,取而代之的是“'s”后缀。有人可以帮忙解释一下这里发生了什么吗? 0.0
哦,如果有人可以为上面的问题 2 提出解决方案,那么我将非常感激 - 因为你会让我的周末免于痛苦!
在此先感谢大家!
欢迎来到令人困惑的编码世界!至少要处理文件编码、终端编码和文件名编码,这三者可能不同。
在Python2.x中,目标是从一个编码的字符串中得到一个Unicode字符串(不同于str
)。问题是您并不总是知道用于 str
的编码,因此很难对其进行解码。
当使用 listdir()
获取文件名时,有一个已记录但经常被忽视的怪癖 - 如果您将 str
传递给 listdir()
,您将得到 str
的编码。这些将根据您的语言环境进行编码。在 Windows 上,这些将是一个 8 位字符集,如 windows-1252
。
或者,传递 listdir()
Unicode 字符串。
例如
os.listdir(u'C:\mydir')
注意 u
前缀
这将return 正确解码 Unicode 文件名。在 Windows 和 OS X 上,只要您的环境语言环境没有被弄乱,这是非常可靠的。
在你的情况下,listdir()
会 return:
u'521001ldrAvisoAcionistas(Retifica\xe7\xe3o)_doc'
再次注意 u
前缀。您现在可以将其打印到您的 PyCharm 控制台,无需修改。
例如
f = filter(os.path.isfile, os.listdir(tmp_path))[0]
print f
至于问题 2,由于时间限制,我没有进一步调查,只是将输出打印为 unicode 字符串,而不是 xlwt 对象。我能够继续这个项目,尽管不了解这里出了什么问题。从这个意义上说,上面的两个问题已经得到了回答。