【问题标题】:'utf-8' codec can't decode byte reading a file in Python3.4 but not in Python2.7'utf-8' 编解码器无法在 Python3.4 中解码字节读取文件,但在 Python2.7 中则无法解码
【发布时间】:2015-03-05 11:09:08
【问题描述】:

我试图在 python2.7 中读取一个文件,它被完美地读取了。我遇到的问题是当我在Python3.4中执行相同的程序然后出现错误:

'utf-8' codec can't decode byte 0xf2 in position 424: invalid continuation byte'

另外,当我在 Windows(使用 python3.4)中运行程序时,不会出现错误。文件的第一行是: Codi;Codi_lloc_anonim;Nom

我的程序代码是:

def lectdict(filename,colkey,colvalue):
    f = open(filename,'r')
    D = dict()

    for line in f:
       if line == '\n': continue
       D[line.split(';')[colkey]] = D.get(line.split(';')[colkey],[]) + [line.split(';')[colvalue]]

f.close
return D

Traduccio = lectdict('Noms_departaments_centres.txt',1,2)

【问题讨论】:

  • 您的文本文件有哪些非 ASCII 内容和编码?
  • 似乎 python 假定文件是 utf-8 但实际上并非如此,你可以试试 open(filename, 'r', encoding='latin-1') 吗?

标签: python python-3.x utf-8


【解决方案1】:

在 Python2 中,

f = open(filename,'r')
for line in f:

从文件中读取行作为字节

在 Python3 中,相同的代码从文件中读取行作为字符串。 Python3 字符串是 Python2 调用的 unicode 对象。这些是解码的字节 根据一些编码。 Python3 中的默认编码是utf-8

错误信息

'utf-8' codec can't decode byte 0xf2 in position 424: invalid continuation byte'

显示 Python3 正在尝试将字节解码为 utf-8。由于出现错误,该文件显然不包含utf-8 编码字节

要解决此问题,您需要指定文件的正确编码

with open(filename, encoding=enc) as f:
    for line in f:

如果你不知道正确的编码,你可以运行这个程序来简单地 尝试 Python 已知的所有编码。如果你幸运的话会有一个 将字节转换为可识别字符的编码。有时更多 一种编码可能似乎起作用,在这种情况下,您需要检查并 仔细比较结果。

# Python3
import pkgutil
import os
import encodings

def all_encodings():
    modnames = set(
        [modname for importer, modname, ispkg in pkgutil.walk_packages(
            path=[os.path.dirname(encodings.__file__)], prefix='')])
    aliases = set(encodings.aliases.aliases.values())
    return modnames.union(aliases)

filename = '/tmp/test'
encodings = all_encodings()
for enc in encodings:
    try:
        with open(filename, encoding=enc) as f:
            # print the encoding and the first 500 characters
            print(enc, f.read(500))
    except Exception:
        pass

【讨论】:

  • 也许cdn.rawgit.com/tripleee/8bit/master/encodings.html#f2 可以帮助您缩小对正确编码的搜索范围。如果您不知道字节应该代表什么,那么试错方法实际上并不可行——随机 8 位编码中的随机字符串是有效的,但在大多数其他 8 位编码中甚至更随机字符串.
  • @tripleee 因为它可以在 Windows 中工作,所以我几乎可以肯定它的 cp1250 因为那将是默认设置,没有?
  • 对于默认值“there”的值,嗯,是的;但不是普遍的。默认代码页首先取决于系统的安装方式。但如果您知道来源是 Windows 的常规美国或西欧安装,我相信 cp1252 将是预期的默认值。它不同于用于东欧语言的cp1250
  • @user3012759 例如,0xF2 在 cp1250 中是 ň 但在 cp1252 中是 ò。
【解决方案2】:

好的,我和@unutbu 告诉我的一样。结果是很多编码其中之一是 cp1250,因此我改变了:

f = open(filename,'r')

f = open(filename,'r', encoding='cp1250')

喜欢@triplee 建议我。现在我可以读取我的文件了。

【讨论】:

    【解决方案3】:

    就我而言,我无法更改编码,因为我的文件实际上是 UTF-8 编码的。但是有些行已损坏并导致相同的错误:

    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 7092: invalid continuation byte
    

    我的决定是以二进制模式打开文件

    open(filename, 'rb')
    

    【讨论】:

      猜你喜欢
      • 2020-07-17
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 2017-09-27
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      相关资源
      最近更新 更多