Python 2.7 literal_eval () со строкой UTF-8 - PullRequest
0 голосов
/ 06 марта 2019

Я обновляю старое приложение для Python 3, но пытаюсь по возможности поддерживать совместимость с Python 2.7.Одна из проблем, с которой я столкнулся, связана с несоответствиями в ast.literal_eval() между Python 2 и 3 при обработке строки UTF-8.

В частности, одна из функций, выполняемых моим приложением, включает:

  1. Чтение строки из текстового файла в кодировке UTF-8, представляющего список имен файлов Python
  2. Преобразование этой строки UTF-8 в список Python с помощью literal_eval()
  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 Ответ

1 голос
/ 07 марта 2019

Как упоминалось в комментариях, 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
...