У меня какой-то мозговой сбой в понимании чтения и записи текста в файл (Python 2.4).
# The string, which has an a-acute in it.
ss = u'Capit\xe1n'
ss8 = ss.encode('utf8')
repr(ss), repr(ss8)
(«u'Capit \ xe1n», «Capit \ xc3 \ xa1n»)
print ss, ss8
print >> open('f1','w'), ss8
>>> file('f1').read()
'Capit\xc3\xa1n\n'
Поэтому я печатаю в Capit\xc3\xa1n
свой любимый редактор, в файле f2.
Затем:
>>> open('f1').read()
'Capit\xc3\xa1n\n'
>>> open('f2').read()
'Capit\\xc3\\xa1n\n'
>>> open('f1').read().decode('utf8')
u'Capit\xe1n\n'
>>> open('f2').read().decode('utf8')
u'Capit\\xc3\\xa1n\n'
Что я здесь не понимаю? Ясно, что я пропускаю какое-то жизненно важное волшебство (или здравый смысл). Что можно ввести в текстовые файлы, чтобы получить правильные преобразования?
Что я действительно не могу понять, так это смысл представления UTF-8, если вы не можете заставить Python распознать его, когда оно приходит извне. Может быть, я должен просто JSON вывести строку и использовать ее вместо этого, так как это имеет превосходное представление! Более того, существует ли ASCII-представление этого объекта Unicode, которое Python будет распознавать и декодировать при входе из файла? Если так, как я могу получить это?
>>> print simplejson.dumps(ss)
'"Capit\u00e1n"'
>>> print >> file('f3','w'), simplejson.dumps(ss)
>>> simplejson.load(open('f3'))
u'Capit\xe1n'
u'\xe1'
это одна кодовая точка Unicode,U+00e1
которая может быть представлена с использованием 1 или более байтов в зависимости от кодировки символов (в utf-8 это 2 байта).b'\xe1'
один байт (число 225), какая буква, если таковая имеется, зависит от кодировки символов, используемой для его декодирования, например, этоб
(U+0431
) в cp1251,с
(U+0441
) в cp866 и т. д.Вместо того, чтобы связываться с методами кодирования и декодирования, мне проще указать кодировку при открытии файла.
io
Модуль (добавлено в Python 2.6) обеспечиваетio.open
функцию, которая имеет параметр кодирования.Используйте метод open из
io
модуля.Затем после вызова функции read (), возвращается закодированный объект Unicode.
Обратите внимание, что в Python 3
io.open
функция является псевдонимом для встроеннойopen
функции. Встроенная функция open поддерживает только аргумент кодирования в Python 3, а не Python 2.Изменить: Ранее этот ответ рекомендовал модуль кодеков . Модуль кодеков может вызвать проблемы при микшировании
read()
иreadline()
, поэтому этот ответ теперь рекомендует вместо этого модуль io .Используйте метод open из модуля кодеков.
Затем после вызова функции read (), возвращается закодированный объект Unicode.
Если вы знаете кодировку файла, использование пакета кодеков будет намного менее запутанным.
См. Http://docs.python.org/library/codecs.html#codecs.open.
источник
open(file,'w')
чтобыcodecs.open(file,'w','utf-8')
решитьcodecs.open(...)
метод также полностью соответствоватьwith open(...):
стилю, гдеwith
заботится о закрытии файла после все сделано? Кажется, все равно работает.with codecs.open(...) as f:
все время.Теперь все, что вам нужно в Python3, это
open(Filename, 'r', encoding='utf-8')
[Изменить на 2016-02-10 для запрашиваемого разъяснения]
Python3 добавил параметр кодирования в свою функцию open. Следующая информация об открытой функции собрана отсюда: https://docs.python.org/3/library/functions.html#open
Таким образом, добавляя
encoding='utf-8'
в качестве параметра в функцию open, чтение и запись файла выполняется как utf8 (который также теперь является кодировкой по умолчанию для всего, что делается в Python).источник
codecs.open('somefile', encoding='utf-8')
stackoverflow.com/a/147756/149428Итак, я нашел решение для того, что я ищу, а именно:
Здесь есть несколько необычных кодеков. Это конкретное чтение позволяет взять представления UTF-8 из Python, скопировать их в файл ASCII и сделать так, чтобы они были прочитаны в Unicode. При декодировании "string-escape" косые черты не удваиваются.
Это учитывает вид поездки туда и обратно, которую я воображал.
источник
(codecs.open(file,"r","utf-8")
и просто,open(file,"r").read().decode("utf-8")
и оба работали отлично.источник
На самом деле это помогло мне прочитать файл с кодировкой UTF-8 в Python 3.2:
источник
Чтобы прочитать строку в Юникоде и затем отправить в HTML, я сделал это:
Полезно для HTTP-серверов на питоне.
источник
Вы наткнулись на общую проблему с кодировками: как определить, в какой кодировке находится файл?
Ответ: Вы не можете, если формат файла не предусматривает это. Например, XML начинается с:
Этот заголовок был тщательно выбран, чтобы его можно было прочитать независимо от кодировки. В вашем случае такой подсказки нет, поэтому ни ваш редактор, ни Python не имеют ни малейшего представления о том, что происходит. Следовательно, вы должны использовать
codecs
модуль и использоватьcodecs.open(path,mode,encoding)
который обеспечивает отсутствующий бит в Python.Что касается вашего редактора, вы должны проверить, предлагает ли он какой-либо способ установить кодировку файла.
Суть UTF-8 в том, чтобы иметь возможность кодировать 21-битные символы (Unicode) как 8-битный поток данных (потому что это единственное, что могут обрабатывать все компьютеры в мире). Но поскольку большинство ОС предшествуют эпохе Unicode, у них нет подходящих инструментов для прикрепления информации о кодировке к файлам на жестком диске.
Следующая проблема - представление в Python. Это прекрасно объясняется в комментарии Heikogerlach . Вы должны понимать, что ваша консоль может отображать только ASCII. Чтобы отобразить Unicode или что-нибудь> = charcode 128, он должен использовать некоторые средства экранирования. В вашем редакторе вы не должны вводить экранированную строку отображения, но что означает эта строка (в этом случае вы должны ввести умлаут и сохранить файл).
Тем не менее, вы можете использовать функцию Python eval (), чтобы превратить экранированную строку в строку:
Как видите, строка "\ xc3" была превращена в один символ. Теперь это 8-битная строка в кодировке UTF-8. Чтобы получить Unicode:
Грегг Линд спросил: я думаю, что здесь не хватает некоторых частей: файл f2 содержит: hex:
codecs.open('f2','rb', 'utf-8')
например, читает их все в отдельных символах (ожидается) Есть ли способ записи в файл в ASCII, который будет работать?Ответ: Это зависит от того, что вы имеете в виду. ASCII не может представлять символы> 127. Таким образом, вам нужно как-то сказать «следующие несколько символов означают что-то особенное», что и делает последовательность «\ x». Он говорит: следующие два символа - это код одного символа. «\ u» делает то же самое, используя четыре символа для кодирования Unicode до 0xFFFF (65535).
Таким образом, вы не можете напрямую писать Unicode в ASCII (потому что ASCII просто не содержит одинаковые символы). Вы можете написать это как строковые экранированные (как в f2); в этом случае файл может быть представлен как ASCII. Или вы можете записать его как UTF-8, в этом случае вам нужен 8-битный безопасный поток.
Ваше решение с использованием
decode('string-escape')
работает, но вы должны знать, сколько памяти вы используете: в три раза больше использованияcodecs.open()
.Помните, что файл - это просто последовательность байтов с 8 битами. Ни биты, ни байты не имеют значения. Это ты говоришь "65 означает" А "". Поскольку он
\xc3\xa1
должен стать «à», но компьютер не имеет средств для этого, вы должны указать это, указав кодировку, которая использовалась при записи файла.источник
кроме того
codecs.open()
, можно использоватьio.open()
для работы с Python2 или Python3 для чтения / записи файла Unicodeпример
источник
with io.open('data.txt', 'w', 'utf-8') as file:
и есть ошибка:TypeError: an integer is required
. После того как я перешел наwith io.open('data.txt', 'w', encoding='utf-8') as file:
и это сработало.Ну, ваш любимый текстовый редактор не понимает, что
\xc3\xa1
это должны быть символьные литералы, но он интерпретирует их как текст. Вот почему вы получаете двойную обратную косую черту в последней строке - теперь это настоящая обратная косая черта +xc3
и т. Д. В вашем файле.Если вы хотите читать и писать закодированные файлы в Python, лучше всего использовать модуль кодеков .
Вставить текст между терминалом и приложениями сложно, потому что вы не знаете, какая программа будет интерпретировать ваш текст, используя какую кодировку. Вы можете попробовать следующее:
Затем вставьте эту строку в ваш редактор и убедитесь, что она хранит ее, используя Latin-1. В предположении, что буфер обмена не искажает строку, туда и обратно должно работать.
источник
Последовательность \ x .. специфична для Python. Это не универсальная escape-последовательность байтов.
То, как вы на самом деле вводите кодировку в кодировке UTF-8, не являющуюся ASCII, зависит от вашей ОС и / или вашего редактора. Вот как вы делаете это в Windows . Для OS X , чтобы войти с острым ударением вы можете просто нажать + , затем , и почти все текстовые редакторы в OS X поддержка UTF-8.optionEA
источник
Вы также можете улучшить исходную
open()
функцию для работы с файлами Unicode, заменив ее на месте, используяpartial
функцию. Прелесть этого решения в том, что вам не нужно менять старый код. Это прозрачно.источник
Я пытался разобрать iCal с помощью Python 2.7.9:
Но я получаю:
и это было исправлено просто:
(Теперь он может напечатать liké á böss.)
источник
Я нашел самый простой подход, изменив кодировку по умолчанию всего сценария на «UTF-8»:
любое
open
,print
или другое утверждение будет просто использоватьutf8
.Работает по крайней мере для
Python 2.7.9
.Thx идет в https://markhneedham.com/blog/2015/05/21/python-unicodeencodeerror-ascii-codec-cant-encode-character-uxfc-in-position-11-ordinal-not-in-range128/ ( посмотри в конец).
источник