LINUX.ORG.RU

[python] encode, decode, unicode.... 8-E

 


0

1

Что-то я запутался с этими методами. Какое-то сильное колдунство тут. Например, выходит, что кодировать строку надо непосредственно при выводе в файл. Если заранее обработать - ошибка получается. Понять как делать - понял, а почему - не совсем. Двигаюсь вперед путем перебора разных вариантов, а это тупой подход. Подскажите, пж, что-нибудь доходчивое почитать, чтобы наконец разобраться, как работать с юникодными стрингами. Желательно с примерами.

★★

Читаем и понимаем общее устройство http://www.joelonsoftware.com/articles/Unicode.html

Применительно к питону (второй версии).

Любая строка попавшая в вашу программу извне - не юникодная, а простой набор байтиков. Этот набор байтиков необходимо раскодировать в Юникод. Обычно это делают как можно раньше и дальше работают уже с Юникодом. В питоне для этого используется метод decode().

Юникодную строку нельзя записать на диск, ее необходимо закодировать как набор байтиков и записать. Обычно это делается как можно позже (непосредственно перед выводом). В питоне для этого используется метод encode().

На примере:

file = open('text.txt', 'rw')

# Прочитаем набор байтиков из файла на диске
data = file.read()
# Раскодируем набор байтиков в юникодную строку
data = data.decode('utf-8')  # Кодировка может быть и другая

# Теперь data - Юникод

# Закодируем юникодную строку обратно в набор байтиков
data = data.encode('utf-8')
# Запишем байты обратно на диск
file.write(data)

file.close()  # Необязательно, но хороший стиль

Ну и вообще-то про это гугл много чего знает.

dccp
()
Ответ на: комментарий от dccp

> Применительно к питону (второй версии).

Напоследок стоит сказать, что в третьей версии "обычные" строки (класс str, литералы виды "строка") - юникодные. И файлы сами умеют перекодировать, во второй версии тоже умеют вроде.

const86 ★★★★★
()
Ответ на: комментарий от dccp

Ну если юзать print, а не file.write тогда не нужен encode.

print >>file, data

Или юзать функцию print из 3-го питона, которая доступна и в 2.6

provaton ★★★★★
()
Ответ на: комментарий от provaton

Ну если юзать print, а не file.write тогда не нужен encode.

Будет неявный вызов encode('ascii')

# -*- coding: utf-8 -*-
print >>open('test.txt', 'w'), u'Привет, мир!'

$ python test.py
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    print >>open('test.txt', 'w'), u'Привет, мир!'
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

И это всегда будет не срабатывать если текст содержит любые не английские символы. Поэтому кодировку надо всегда указывать явно.

Ну и использовать print для записи в файл я бы не советовал, это одно из неудачных решений в дизайне языка от которого все отказались.

dccp
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.