ast.literal_eval 竟然引发 UnicodeDecodeError

2 投票
2 回答
1886 浏览
提问于 2025-04-18 20:57

好的,来看看这个问题...

  • 一个Unicode字符串会被编码成Python 2.x的字符串(实际上是字节序列)
  • 一个Python 2.x的字符串会被解码成Unicode字符串

Python UnicodeDecodeError - 我是不是误解了编码?

我有一段Python 2.7的代码

try:
    print '***'
    print type(relationsline)
    relationsline = relationsline.decode("ascii", "ignore")
    print type(relationsline)
    relationsline = relationsline.encode("ascii", "ignore")
    print type(relationsline)
    relations = ast.literal_eval(relationsline)
except ValueError:
    return
except UnicodeDecodeError:
    return

上面代码的最后一行有时会抛出一个错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 341: ordinal not in range(128)

我原本认为这个过程应该是这样的:(1) 从一个有某种(未知)编码的字符串开始,(2) 将其解码成Unicode类型,表示一个字符字符串,使用ASCII编码,同时忽略所有不能用ASCII编码的字符,(3) 将Unicode类型编码成一个ASCII编码的字符串,忽略所有不能用ASCII表示的字符。

这是完整的错误追踪信息:

Traceback (most recent call last):
  File "outputprocessor.py", line 69, in <module>
    getPersonRelations(lines, fname)
  File "outputprocessor.py", line 41, in getPersonRelations
    relations = ast.literal_eval(relationsline)
  File "/usr/lib/python2.7/ast.py", line 49, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "/usr/lib/python2.7/ast.py", line 37, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 341: ordinal not in range(128)
                      ^
SyntaxError: invalid syntax

但显然这里面有些地方是错的。更让人困惑的是,UnicodeDecodeError并没有捕捉到这个错误。我漏掉了什么呢?也许这就是问题所在?http://bugs.python.org/issue22221

2 个回答

0

你正在尝试用 literal_eval 来处理从 relationsline = relationsline.encode("ascii", "ignore") 这行代码得到的错误信息。

你需要把 literal_eval 的检查放到一个单独的 try/except 块里,或者在你原来的 try 块中捕捉这个错误,或者以某种方式过滤输入。

1

仔细看看错误信息,它显示的是一个 SyntaxError(语法错误)。

你正在尝试用 literal_eval 来处理这个字符串 "UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 341: ordinal not in range(128)"。你可以对这个字符串进行编码或解码,但 ast 不知道该怎么处理它,因为这显然不是一个有效的 Python 字面量。

看看这个:

>>> import ast
>>> ast.literal_eval('''UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 341: ordinal not in range(128)''')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/ast.py", line 49, in literal_eval
    node_or_string = parse(node_or_string, mode='eval')
  File "/usr/lib/python2.7/ast.py", line 37, in parse
    return compile(source, filename, mode, PyCF_ONLY_AST)
  File "<unknown>", line 1
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 341: ordinal not in range(128)
                      ^
SyntaxError: invalid syntax

我建议你检查一下传递这些字符串给你函数的源头,它正在生成一些无效的输入。

撰写回答