我试图让一个 Python 3 程序对一个充满信息的文本文件进行一些操作。但是,当尝试读取文件时,出现以下错误:
Traceback (most recent call last):
File "SCRIPT LOCATION", line NUMBER, in <module>
text = file.read()`
File "C:\Python31\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 2907500: character maps to `<undefined>`
-Xutf8
(应该修复它)。
有问题的文件未使用 CP1252
编码。它正在使用另一种编码。你必须自己弄清楚哪一个。常见的是 Latin-1
和 UTF-8
。由于 0x90 实际上在 Latin-1
中没有任何意义,因此 UTF-8
(其中 0x90 是一个连续字节)更有可能。
您在打开文件时指定编码:
file = open(filename, encoding="utf8")
如果 file = open(filename, encoding="utf-8")
不起作用,请尝试
file = open(filename, errors="ignore")
,如果您想删除不需要的字符。 (docs)
或者,如果您不需要解码文件,例如将文件上传到网站,请使用:
open(filename, 'rb')
其中 r = 读数,b = 二进制
b
将产生 bytes
而不是 str
数据。正如您所注意到的,如果您不需要以任何方式处理字节,这是合适的。
作为 @LennartRegebro's answer 的扩展:
如果您不知道您的文件使用什么编码并且上面的解决方案不起作用(它不是 utf8
)并且您发现自己只是在猜测 - 您可以使用 online tools 来识别是什么编码。它们并不完美,但通常工作得很好。弄清楚编码后,您应该可以使用上面的解决方案。
编辑:(从评论中复制)
一个非常流行的文本编辑器 Sublime Text
有一个显示编码的命令,如果它已设置...
转到查看 -> 显示控制台(或 Ctrl+`)
https://i.stack.imgur.com/TvXZL.png
在底部 view.encoding() 的字段中输入并希望最好(我无法得到任何东西,但未定义但也许你会有更好的运气......)
https://i.stack.imgur.com/yz8nN.png
:set fileencoding
(from this link)
view.encoding()
。
TLDR: 尝试:file = open(filename, encoding='cp437')
为什么?当一个人使用:
file = open(filename)
text = file.read()
Python 假定该文件使用与当前环境相同的代码页(cp1252
在开篇文章的情况下)并尝试将其解码为自己的默认 UTF-8
。如果文件包含此代码页中未定义的值的字符(如 0x90),我们将得到 UnicodeDecodeError
。有时我们不知道文件的编码,有时文件的编码可能未被 Python 处理(例如 cp790
),有时文件可能包含混合编码。
如果不需要这些字符,可以决定用问号替换它们,如下所示:
file = open(filename, errors='replace')
另一种解决方法是使用:
file = open(filename, errors='ignore')
然后字符保持不变,但其他错误也将被掩盖。
一个很好的解决方案是指定编码,但不是任何编码(如 cp1252
),而是定义了所有字符的编码(如 cp437
):
file = open(filename, encoding='cp437')
代码页 437 是原始的 DOS 编码。所有代码都已定义,因此在读取文件时没有错误,没有错误被屏蔽,字符被保留(不是完全完好无损,但仍然可以区分)。
不要再浪费时间了,只需将以下 encoding="cp437"
和 errors='ignore'
添加到您的代码中即可读写:
open('filename.csv', encoding="cp437", errors='ignore')
open(file_name, 'w', newline='', encoding="cp437", errors='ignore')
神速
0x90
解码为 'É'
。检查 b'\x90'.decode('cp437')
。
对于那些在 Windows 中使用 Anaconda 的人来说,我遇到了同样的问题。 Notepad++帮我解决了。
在记事本++中打开文件。在右下角它会告诉你当前的文件编码。在顶部菜单中,在“查看”旁边找到“编码”。在“编码”中转到“字符集”,然后耐心地寻找您需要的编码。在我的情况下,编码“Windows-1252”是在“西欧”下找到的
在应用建议的解决方案之前,您可以检查出现在您的文件(和错误日志中)中的 Unicode 字符是什么,在这种情况下是 0x90
:https://unicodelookup.com/#0x90/1(或直接在 Unicode Consortium 站点 http://www.unicode.org/charts/ 通过搜索0x0090
)
然后考虑将其从文件中删除。
对我来说,使用 utf16 编码有效
file = open('filename.csv', encoding="utf16")
在较新版本的 Python(从 3.7 开始)中,您可以添加解释器选项 -Xutf8
,它应该可以解决您的问题。如果你使用 Pycharm,只需 Run > 编辑配置(在标签配置中将字段解释器选项中的值更改为-Xutf8
)。
或者,等效地,您可以将环境变量 PYTHONUTF8
设置为 1。
https://i.stack.imgur.com/imf7s.png
不定期副业成功案例分享
io
模块:io.open(filename,encoding="utf8")
filename = "C:\Report.txt" with open(filename,encoding ="utf8") as my_file: text = my_file.read() print(text)
即使在使用它之后,我也会遇到同样的错误。我也尝试过其他编码,但都是徒劳的。在此代码中,我也使用from geotext import GeoText
。请提出解决方案。