Наборы Python и хорошая кодировка

Я использую Python2 и пытаюсь поместить много слов французского словаря в заданный объект, но у меня всегда возникают проблемы с кодировкой слов с акцентом.

Это мой основной код (эта часть читает текстовый файл):

#!/usr/bin/env python
# -*- encoding: utf-8 -*- 
from sets import Set
with open('.../test_unicode.txt', 'r') as word:
    lines = word.readlines()
    print(lines)

А это результат моей печати:

['\xc3\xa9l\xc3\xa9phants\n', 'bonjour\n', '\xc3\xa9l\xc3\xa8ves\n']

Это мой текстовый файл для этого примера:

éléphants
bonjour
élèves

После этого это продолжение моего основного кода, который помещает слова в набор Python:

dict_word = Set()
for line in lines:
    print(line)
    dict_word.add(line[:-1].upper()) #Get rid of the '\n'

print(dict_word)

Это результат моей печати:

Set(['\xc3\xa9L\xc3\xa8VES', 'BONJOUR', '\xc3\xa9L\xc3\xa9PHANTS'])

Я хочу, чтобы этот вывод:

Set(['ÉLÈVES', 'BONJOUR', 'ÉLÉPHANTS'])

Но я не могу понять, как получить этот результат. Я пробовал много способов, включая размещение этой строки '# -- encoding: utf-8 --' в верхней части моего файла. Я также пробовал «с codecs.open()», но это тоже не сработало.

Спасибо!


person Tom    schedule 15.07.2020    source источник
comment
Какая кодировка текстового файла? Это utf-8, кодовая страница Windows, utf-16?   -  person tdelaney    schedule 15.07.2020
comment
Кодировка моего текстового файла: utf-8   -  person Tom    schedule 15.07.2020
comment
Проблема может заключаться в том, что Python не будет выводить нужную вам строку. Вот почему Python 3 всегда использует Unicode для строк.   -  person Mark Ransom    schedule 15.07.2020
comment
@MarkRansom - это зависит от того, как вы его выводите. Если вы напечатаете строку и ваш sys.stdout.encoding поддерживает символы, она будет напечатана.   -  person tdelaney    schedule 15.07.2020
comment
@tdelaney, если вы печатаете строки Unicode, тогда будет использоваться sys.stdout.encoding, иначе строка байтов не будет переведена.   -  person Mark Ransom    schedule 15.07.2020
comment
@MarkRansom - Если вы читаете файл в кодировке utf-8 как str, а ваш терминал - utf-8, он будет печатать. Вы получаете строку с кодировкой utf-8, и, поскольку это не строка unicode, она не декодируется, но ее формат ожидает терминал, и она все еще работает. utf-8 и до сих пор работает.   -  person tdelaney    schedule 15.07.2020
comment
@tdelaney, вы не должны много использовать Windows.   -  person Mark Ransom    schedule 15.07.2020
comment
@MarkRansom - то же самое относится и к кодовым страницам Windows. Программы на Python 2, как правило, работали в группе людей, использующих данную кодовую страницу, но переставали работать, когда файлы использовались совместно на машинах с разными кодовыми страницами. Вот почему unicode опоздал с python и был просто добавлен в 2.x.   -  person tdelaney    schedule 15.07.2020
comment
@tdelaney Я сказал это, потому что консоль Windows крайне редко правильно отображает байты UTF-8. Если ваши наборы входных и выходных символов совпадали, тогда жизнь была прекрасной, и поэтому Python 2 так долго сходил с рук.   -  person Mark Ransom    schedule 15.07.2020
comment
Есть ли способ записать то, что находится в наборе python, в другом текстовом файле? С заглавными буквами и ударениями?   -  person Tom    schedule 15.07.2020


Ответы (3)


В python 2 вы можете использовать модуль codecs для чтения файла с кодировкой. Помните, что представление repr строки юникода будет выглядеть странно (начинается с u, экранирует элементы юникода), но фактическая строка на самом деле является юникодом.

#!/usr/bin/env python
# -*- encoding: utf-8 -*- 
from sets import Set
import codecs
with codecs.open('test.txt', encoding='utf-8') as word:
    lines = [line.strip() for line in word.readlines()]
    # since you print the list, it shows you the repr of its values
    print(lines)
    # but they really are unicode
    for line in lines:
        print(line)

Вывод показывает представление Unicode при печати списка, но реальную строку при печати самих строк.

[u'\xe9l\xe9phants', u'bonjour', u'\xe9l\xe8ves']
éléphants
bonjour
élèves
person tdelaney    schedule 15.07.2020

Причина, вероятно, в том, что вы читаете файл, используя неправильную кодировку.

В Python 3 вы просто переключитесь:

  • от 1_
  • to with open('.../test_unicode.txt', 'r', encoding="utf-8") as word:

В Python 2 кажется, что вы можете сделать что-то вроде этого: Python 3 открыт (encoding=utf-8) для Python 2

т.е. используйте io.open (сначала нужно import io) и укажите encoding="utf-8". Я ожидал, что это будет работать и с codecs.open, если вы укажете тот же аргумент ключевого слова.

person wjakobw    schedule 15.07.2020

Вы можете попытаться вывести кодировку ввода

from sets import Set
import chardet
with open('.../test_unicode.txt', 'rb') as word:
    bin_data = word.readlines()
    enc = chardet.detect(bin_data)
    lines = bin_data.decode(enc['encoding'])
    print(lines)
person b0lle b    schedule 15.07.2020