Python 2 сокет и строковое кодирование - PullRequest
0 голосов
/ 17 марта 2012

Я читаю файл в utf-8 в Unicode, и я не получаю никаких ошибок.

try:
        f = codecs.open(fil_name, "r","utf-8")
        f_str = f.read()

То есть строка f_str находится в "Unicode" Позже в программе я должен отправить строку (u) из f_str в сокет. Я пытаюсь преобразовать строку обратно в "utf-8".

usock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
usock.connect(("xxx server", 123))
usock.send("TEXT %s\nENDQ\n" % f_str.replace("\n", " ").encode("utf-8"))

здесь я получаю сообщение об ошибке:

usock.send("TEXT %s\nENDQ\n" % text.replace("\n", " ").encode("utf-8"))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 41: ordinal not in range(128)

В моем тексте есть символы, которые не могут быть закодированы с помощью чистого ASCII (äö ..), но это не проблема для utf-8 или latin-1. Почему я получаю эту ошибку? Я не использую ASCII, я использую Unicode / UTF-8 ???

Ответы [ 3 ]

1 голос
/ 17 марта 2012

Ваш строковый литерал является байтовой строкой. Когда вы пытаетесь вставить его в него, Python неявно попытается преобразовать в байтовую строку, используя кодировку по умолчанию (ascii).

Есть несколько способов это исправить. Одним из них является просто использование Python 3. ;-)

Если вы используете Python 2, поместите в верхнюю часть исходного файла следующее:

from __future__ import unicode_literals

Тогда ваш литерал также будет в юникоде.

Вы также можете добавить в строку префикс «u».

Другая проблема с этой строкой - приоритет. Операция форматирования '% s' - это то, что пытается неявно преобразовать ваш юникод в строку, используя кодек ascii, после завершения правой части.

Итак, попробуйте это:

(u"TEXT %s\nENDQ\n" % f_str.replace(u"\n", u" ")).encode("utf-8")
0 голосов
/ 17 марта 2012

Ошибка в этой строке

usock.send("TEXT %s\nENDQ\n" % text.replace("\n", " ").encode("utf-8"))

Я могу воспроизвести похожую ошибку следующим образом:

In [23]: text = 'äö'

In [24]: 'TEXT %s'%text.replace("n", " ").encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

Хотя вы показали, что f_str - это unicode, каким-то образом text - это str объект. Некоторая дополнительная обработка, которую вы выполняете между f_str и text, вероятно, делает text a str.

Если вы можете преобразовать все входные данные в юникод, работать с ними как с юникодом и преобразовывать обратно в определенную кодировку только при выводе (при необходимости), ваша проблема должна быть исправлена.

0 голосов
/ 17 марта 2012

Начните с проверки очевидного контрольного списка Python Unicode:

  1. ставит -*- encoding:utf-8 -*- вверху каждого исходного файла
  2. проверка, имеет ли кодировка текстового файла utf-8 (большинство по умолчанию - ascii 1255)

также

зачем вам кодировать ('utf-8'), если это уже юникод? какое сообщение об ошибке вы получите, если не сделаете этого?

и вы пытались явно объявить f_str как Unicode: как

f_str=unicode(f_str)

также попробуйте напечатать f_str и проверьте, правильно ли вы получаете результат раньше ... возможно, это проблема с данными

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...