UTF-8 Python проблемы с Google Datastore - PullRequest
       18

UTF-8 Python проблемы с Google Datastore

1 голос
/ 05 сентября 2011

Я бродил по этим форумам, задавая вопросы о проблемах, связанных с кодированием / декодированием Python и UTF-8.

На этот раз я наткнулся на что-то, что поначалу казалось легкой проблемой.

В моем предыдущем вопросе (http://stackoverflow.com/questions/7138797/problems-with-python-in-google-app-engine-utf-8-and-ascii) я спросил, как обеспечить правильное добавление строк UTF-8 к переменным:

Messages.append(ChatMessage(chatter, msg))

Решение было что-то вроде этого:

Messages.append(ChatMessage(chatter.encode( "utf-8" ), msg.encode( "utf-8" )))

Довольно просто.

Однако теперь я столкнулся с проблемой отправки данных в хранилище данных Google App Engine. Код из книги, которую я использовал (Код в облаке), выглядел следующим образом (япропустил лишние части):

#START: ChatMessage
class ChatMessage(db.Model):
    user = db.StringProperty(required=True)
    timestamp = db.DateTimeProperty(auto_now_add=True)
    message = db.TextProperty(required=True)

    def __str__(self):
        return "%s (%s): %s" % (self.user, self.timestamp, self.message)
#END: ChatMessage

# START: PostHandler
class ChatRoomPoster(webapp.RequestHandler):
    def post(self):
        chatter = self.request.get("name")
        msgtext = self.request.get("message")
        msg = ChatMessage(user=chatter, message=msgtext)
        msg.put() #<callout id="co.put"/>
        self.redirect('/')        
# END: PostHandler

Я думал, что замена части PostHandler следующим битом:

msg = ChatMessage(user=chatter.encode( "utf-8" ), message=msgtext.encode( "utf-8" ))

... сделает свое дело. К сожалению, это сделалне получилось. Я все еще продолжаю получать

File "/base/data/home/apps/s~markcc-chatroom-one-pl/1.353054484690143927/pchat.py", line 147,      in post
msg = ChatMessage(user=chatter.encode( "utf-8" ), message=msgtext.encode( "utf-8" ))

 UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal not in range(128)

Естественно, я объявил (# - - кодирование: utf-8 - -) и поставил:

self.response.headers['Content-Type'] = 'text/html; charset=UTF-8'

в файле. Это не делает ничего, чтобы облегчить проблему.

Как видите, я не очень хорошо разбираюсь в Python, и проблемы с кодированием / декодированием для меня немного новы.Буду признателен за вашу помощь.Если кто-нибудь может объяснить мне, где я ошибся в этом случае и какие методы использовать, чтобы избежать подобных затруднений в будущем?Заранее спасибо.

1 Ответ

3 голосов
/ 05 сентября 2011

encode превращает юникод в байты, а decode превращает байты в юникод. Вы должны быть осторожны, чтобы не смешать два. Ваша ошибка означает либо:

  1. chatter или msgtext - это уже байты, и вы пытаетесь его кодировать. Одна из худших «особенностей» Python 2 заключается в том, что он позволяет вам делать это - он пытается сначала декодировать байтов, используя ascii (наиболее ограниченную кодировку), а затем перекодировать их как угодно ». мы просили. Это исправлено в Python 3, но вы не можете использовать это в App Engine.

  2. App Engine ожидает сохранения Unicode ( это делает ). Так что вам нужно передать ей строку Unicode без ее кодирования. Фактически, если ваши данные уже находятся в строке байтов, вам необходимо декодировать , прежде чем вы сможете их сохранить.

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

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

...