Я обошел эти форумы, задавая вопросы о проблемах, связанных с кодировкой/декодированием 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" )))
Довольно просто.
Однако теперь я столкнулся с проблемой отправки данных в Datastore Google App Engine. Код из книги, которую я использовал (Code in the Cloud), выглядел следующим образом (я пропустил лишние части):
#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, и проблемы с кодированием/декодированием для меня немного новизны. Буду признателен за вашу помощь. Если бы кто-нибудь мог объяснить мне, где я ошибся в этом случае и какие методы следует использовать, чтобы избежать подобных затруднений в будущем? Заранее спасибо.
encode
превращает unicode в байты, а decode
превращает байты в unicode. Вы должны быть осторожны, чтобы не смешивать их. Ваша ошибка означает:
chatter
или msgtext
- это уже байты, и вы пытаетесь его закодировать. Одна из худших "особенностей" Python 2 заключается в том, что он позволяет это сделать - он пытается сначала декодировать байты, используя ascii (наиболее ограниченную кодировку), а затем перекодировать их с помощью того, что вы просили. Это исправлено в Python 3, но вы не можете использовать это в App Engine.
App Engine ожидает сохранения unicode (он делает). Поэтому вам нужно передать строку unicode без ее кодирования. Фактически, если ваши данные уже находятся в байтовом режиме, вам нужно будет декодировать его, прежде чем вы сможете его сохранить.
Короче говоря, первое, что нужно попробовать, это просто не вызывать .encode
прежде чем хранить данные.
(Возможно, я указал вам это раньше, но если нет, пожалуйста, найдите время, чтобы прочитать эту статью о юникоде)