具有UTF-8字符串的Python 2.7literal_eval()

时间:2019-03-06 15:18:11

标签: python-3.x python-2.7 utf-8 eval unicode-string

我正在为Python 3更新一个较旧的应用程序,但尝试尽可能地保持与Python 2.7的兼容性。处理UTF-8字符串时,我遇到的问题之一是Python 2和3之间的ast.literal_eval()不一致。

具体地说,我的应用程序执行的功能之一涉及:

  1. 从表示文件名的Python列表的UTF-8编码的文本文件中读取字符串
  2. 通过literal_eval()将该UTF-8字符串转换为Python列表
  3. 使用该列表访问这些文件并执行其他处理。

我的测试.txt文件具有以下字符串:

  

['FileName1.txt','CP1252-1-àlacrème.txt','dUTF8-1-木兰辞.txt']

我正在使用这个简短的测试脚本来模拟大型应用程序的工作:

import io
from ast import literal_eval

with io.open('z.txt','r',encoding='utf_8') as inFile:
    inStr = inFile.read()
print('Input string is length '+str(len(inStr)))

fileList = literal_eval(inStr)
print(fileList)

现在,当我在Python 3上运行此测试脚本时,我得到以下结果(一切正常,并按预期):

  

输入字符串的长度为61

     

['FileName1.txt','CP1252-1-àlacrème.txt','dUTF8-1-???。txt']

(问号是预期的,因为这是Windows CMD窗口;它不处理非拉丁1字符)

但是无论如何,当我在Python 2.7上使用相同文件运行相同脚本时,会得到以下结果:

  

输入字符串的长度为61

     

['FileName1.txt','CP1252-1- \ xc3 \ xa0lacr \ xc3 \ xa8me.txt','dUTF8-1- \ xe6 \ x9c \ xa8 \ xe5 \ x85 \ xb0 \ xe8 \ xbe \ x9e .txt']

因此literal_eval()在结果列表中未维护UTF-8编码。 (或者,我想尝试来保持编码,但是最好的办法是将非ASCII数据表示为单个字节值。)

我的问题是:有什么方法可以使Python 2 literal_eval()得到与Python 3版本相同的结果?还是我以此为限制?

1 个答案:

答案 0 :(得分:1)

如注释中所述,输入ast.literal_eval在Python 2和3之间的解析方式有所不同。最好不要将Python源代码编写为数据文件,而应将pandas这样的模块与.csv文件一起使用:

如果输入的是具有内容的UTF-8文件:

FileName1.txt,CP1252-1-àlacrème.txt,dUTF8-1-木兰辞.txt

然后pandas可以通过以下方式读取它:

import pandas as pd

data = pd.read_csv('test.txt',encoding='utf8',header=None)
print(data)

输出(Windows终端Python 3,需要适当的字体):

               0                      1                2
0  FileName1.txt  CP1252-1-àlacrème.txt  dUTF8-1-木兰辞.txt

输出(Windows IDLE,控制台中的Python 2需要适当的代码页才能查看表意文字):

               0                      1                2
0  FileName1.txt  CP1252-1-àlacrème.txt  dUTF8-1-木兰辞.txt