Запись текста Unicode в текстовый файл?
я вытаскиваю данные из документа Google, обрабатываю их и записываю в файл (который в конечном итоге я вставлю на страницу Wordpress).
Он имеет некоторые символы, отличные от ASCII. Как безопасно преобразовать их в символы, которые можно использовать в HTML-источнике?
В настоящее время я конвертирую все в Unicode по пути, объединяя все это вместе в строку Python, а затем делаю:
import codecs
f = codecs.open('out.txt', mode="w", encoding="iso-8859-1")
f.write(all_html.encode("iso-8859-1", "replace"))
в последней строке есть ошибка кодирования:
UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0xa0 в позиции 12286: порядковый номер не в диапазон(128)
частичное решение:
этот Python работает без ошибок:
row = [unicode(x.strip()) if x is not None else u'' for x in row]
all_html = row[0] + "<br/>" + row[1]
f = open('out.txt', 'w')
f.write(all_html.encode("utf-8")
но тогда, если я открою фактический текстовый файл, я вижу много символов, таких как:
Qur’an
может быть, мне нужно написать что-то, кроме текстового файла?
7 ответов
общайтесь исключительно с объектами unicode как можно больше, декодируя вещи в объекты unicode, когда вы их впервые получаете, и кодируя их по мере необходимости на выходе.
Если ваша строка на самом деле является объектом unicode, вам нужно преобразовать ее в объект строки в кодировке unicode, прежде чем писать его в файл:
foo = u'Δ, Й, ק, م, ๗, あ, 叶, 葉, and 말.'
f = open('test', 'w')
f.write(foo.encode('utf8'))
f.close()
когда вы снова прочтете этот файл, вы получите строку в юникоде, которую вы можете декодировать в объект Юникода:
f = file('test', 'r')
print f.read().decode('utf8')
в Python 2.6+, вы могли бы использовать io.open()
это значение по умолчанию (builtin open()
) на Python 3:
import io
with io.open(filename, 'w', encoding=character_encoding) as file:
file.write(unicode_text)
это может быть удобнее, если вам нужно писать текст постепенно (вам не нужно звонить unicode_text.encode(character_encoding)
несколько раз). В отличие от codecs
модуль io
модуль имеет правильную универсальную поддержку newlines.
файл codecs.open
- это файл, который занимает unicode
data, кодирует его в iso-8859-1
и записывает его в файл. Однако то, что вы пытаетесь написать, не unicode
, ты unicode
и закодировать его в iso-8859-1
сами. Вот что такое unicode.encode
метод делает, и результатом кодирования строки unicode является bytestring (a str
тип.)
вы должны либо использовать normal open()
и кодировать Юникод самостоятельно, или (как правило, лучшая идея) использовать codecs.open()
и не зашифровать сами данные.
предисловие: будет ли ваш зритель работать?
убедитесь, что ваш просмотрщик/редактор/терминал (однако вы взаимодействуете с вашим файлом в кодировке utf-8) может прочитать файл. Это часто проблема на окна, например, блокнот.
запись текста Unicode в текстовый файл?
в Python 2, Используйте open
С io
модуль (это то же самое, что и встроенный open
в Python 3):
import io
лучшие практика, в общем, используйте UTF-8
для записи в файлы (нам даже не нужно беспокоиться о порядке байтов с utf-8).
encoding = 'utf-8'
utf-8-самая современная и универсально используемая кодировка-она работает во всех веб-браузерах, большинстве текстовых редакторов (см. настройки, если у вас есть проблемы) и большинстве терминалов/оболочек.
в Windows вы можете попробовать utf-16le
если вы ограничены просмотром вывода в блокноте (или другом ограниченном средстве просмотра).
encoding = 'utf-16le' # sorry, Windows users... :(
и просто откройте его с помощью context manager и напишите свои символы unicode:
with io.open(filename, 'w', encoding=encoding) as f:
f.write(unicode_object)
пример использования многие символы Unicode
вот пример, который пытается отобразить каждый возможный символ шириной до трех битов (4-это максимум, но это будет немного далеко) от цифрового представления (в целых числах) до кодированного вывода для печати вместе с его именем, если это возможно (поместите это в файл с именем uni.py
):
from __future__ import print_function
import io
from unicodedata import name, category
from curses.ascii import controlnames
from collections import Counter
try: # use these if Python 2
unicode_chr, range = unichr, xrange
except NameError: # Python 3
unicode_chr = chr
exclude_categories = set(('Co', 'Cn'))
counts = Counter()
control_names = dict(enumerate(controlnames))
with io.open('unidata', 'w', encoding='utf-8') as f:
for x in range((2**8)**3):
try:
char = unicode_chr(x)
except ValueError:
continue # can't map to unicode, try next x
cat = category(char)
counts.update((cat,))
if cat in exclude_categories:
continue # get rid of noise & greatly shorten result file
try:
uname = name(char)
except ValueError: # probably control character, don't use actual
uname = control_names.get(x, '')
f.write(u'{0:>6x} {1} {2}\n'.format(x, cat, uname))
else:
f.write(u'{0:>6x} {1} {2} {3}\n'.format(x, cat, char, uname))
# may as well describe the types we logged.
for cat, count in counts.items():
print('{0} chars of category, {1}'.format(count, cat))
это должно выполняться в порядке около минуты, и вы можете просмотреть файл данных, и если ваш просмотрщик файлов может отображать unicode, вы увидите его. Информацию о категориях можно найти здесь. Основываясь на подсчетах, мы, вероятно, можем улучшить наши результаты, исключив категории Cn и Co, которые не имеют связанных с ними символов.
$ python uni.py
он будет отображать шестнадцатеричное отображение, категория, символ (если не удается получить имя, поэтому, вероятно, управляющий символ) и имя символа. например,
рекомендую less
в Unix или Cygwin (не печатайте / cat весь файл на выходе):
$ less unidata
например, будет отображаться аналогично следующим строкам, которые я выбрал из него с помощью Python 2 (unicode 5.2):
0 Cc NUL
20 Zs SPACE
21 Po ! EXCLAMATION MARK
b6 So ¶ PILCROW SIGN
d0 Lu Ð LATIN CAPITAL LETTER ETH
e59 Nd ๙ THAI DIGIT NINE
2887 So ⢇ BRAILLE PATTERN DOTS-1238
bc13 Lo 밓 HANGUL SYLLABLE MIH
ffeb Sm → HALFWIDTH RIGHTWARDS ARROW
мой Python 3.5 от Anaconda имеет unicode 8.0, я бы предположил, что большинство 3 будет.
обработка строк Unicode стандартизирована в Python 3.
- Char хранятся в Unicode
-
вам нужно только открыть файл в utf-8
out1 = "(嘉南大圳 ㄐㄧㄚ ㄋㄢˊ ㄉㄚˋ ㄗㄨㄣˋ )" fobj = open("t1.txt", "w", encoding="utf-8") fobj.write(out1) fobj.close()
как печатать символы юникода в файл:
сохраните это в файл: foo.py:
#!/usr/bin/python -tt
# -*- coding: utf-8 -*-
import codecs
import sys
UTF8Writer = codecs.getwriter('utf8')
sys.stdout = UTF8Writer(sys.stdout)
print(u'e with obfuscation: é')
запустите его и выведите в файл:
python foo.py > tmp.txt
открыть tmp.TXT и посмотрите внутрь, вы видите это:
el@apollo:~$ cat tmp.txt
e with obfuscation: é
таким образом, вы сохранили unicode e с меткой обфускации на нем в файл.
эта ошибка возникает, когда вы пытаетесь кодировать строку, отличную от unicode: она пытается декодировать ее, предполагая, что она находится в обычном ASCII. Есть две возможности:--3-->
- вы кодируете его в bytestring, но потому, что вы использовали кодеки.open, метод write ожидает объект unicode. Итак, вы кодируете его, и он пытается декодировать его снова. Попробуйте:.
- all_html на самом деле не является объектом unicode. Когда вы делаете
.encode(...)
, Он сначала пытается расшифровать он.