Проблемы с Python в Google App Engine - UTF-8 и ASCII - PullRequest
0 голосов
/ 21 августа 2011

Итак, последние несколько дней я пытался изучать Python в App Engine. Однако я столкнулся с рядом проблем с кодировкой ASCII и UTF. Самый свежий выпуск выглядит следующим образом:

У меня есть следующий фрагмент кода упрощенного чата из книги «Код в облаке»

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import datetime


# START: MainPage
class ChatMessage(object):
def __init__(self, user, msg):
    self.user = user
    self.message = msg
    self.time = datetime.datetime.now()

def __str__(self):
    return "%s (%s): %s" % (self.user, self.time, self.message)

Messages = []

class ChatRoomPage(webapp.RequestHandler):
def get(self):
    self.response.headers["Content-Type"] = "text/html"
    self.response.out.write("""
       <html>
         <head>
           <title>MarkCC's AppEngine Chat Room</title>
         </head>
         <body>
           <h1>Welcome to MarkCC's AppEngine Chat Room</h1>
           <p>(Current time is %s)</p>
       """ % (datetime.datetime.now()))
    # Output the set of chat messages
    global Messages
    for msg in Messages:
        self.response.out.write("<p>%s</p>" % msg)
    self.response.out.write("""
       <form action="" method="post">
       <div><b>Name:</b> 
       <textarea name="name" rows="1" cols="20"></textarea></div>
       <p><b>Message</b></p>
       <div><textarea name="message" rows="5" cols="60"></textarea></div>
       <div><input type="submit" value="Send ChatMessage"></input></div>
       </form>
     </body>
   </html>
   """)
 # END: MainPage    
 # START: PostHandler
def post(self):
    chatter = self.request.get("name")
    msg = self.request.get("message")
    global Messages
    Messages.append(ChatMessage(chatter, msg))
    # Now that we've added the message to the chat, we'll redirect
    # to the root page, which will make the user's browser refresh to
    # show the chat including their new message.
    self.redirect('/')        
# END: PostHandler




# START: Frame
chatapp = webapp.WSGIApplication([('/', ChatRoomPage)])


def main():
run_wsgi_app(chatapp)

if __name__ == "__main__":
main()
# END: Frame

Хорошо работает на английском языке. Однако, когда я добавляю несколько нестандартных символов, начинаются всевозможные проблемы

Прежде всего, чтобы вещь действительно отображала символы в HTML, я добавляю метатег - charset = UTF-8 "и т. Д.

Любопытно, что если вы вводите нестандартные буквы, программа хорошо обрабатывает их и отображает без проблем. Тем не менее, он не загружается, если я сам вводю не-ascii-письма в веб-макет самостоятельно, используя скрипт. Я понял, что добавление строки кодирования utf-8 будет работать. Поэтому я добавил (# - - кодировка: utf-8 - -). Этого было недостаточно. Конечно, я забыл сохранить файл в формате UTF-8. После этого программа запустилась.

Это был бы хороший конец истории, увы ....

Не работает

Короче говоря, этот код:

# -*- coding: utf-8 -*-
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import datetime


# START: MainPage
class ChatMessage(object):
def __init__(self, user, msg):
    self.user = user
    self.message = msg
    self.time = datetime.datetime.now()

def __str__(self):
    return "%s (%s): %s" % (self.user, self.time, self.message)

Messages = []
class ChatRoomPage(webapp.RequestHandler):
def get(self):
    self.response.headers["Content-Type"] = "text/html"
    self.response.out.write("""
       <html>
         <head>
           <title>Witaj w pokoju czatu MarkCC w App Engine</title>
           <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
         </head>
         <body>
           <h1>Witaj w pokoju czatu MarkCC w App Engine</h1>
           <p>(Dokladny czas Twojego logowania to: %s)</p>
       """ % (datetime.datetime.now()))
    # Output the set of chat messages
    global Messages
    for msg in Messages:
        self.response.out.write("<p>%s</p>" % msg)
    self.response.out.write("""
       <form action="" method="post">
       <div><b>Twój Nick:</b> 
       <textarea name="name" rows="1" cols="20"></textarea></div>
       <p><b>Twoja Wiadomość</b></p>
       <div><textarea name="message" rows="5" cols="60"></textarea></div>
       <div><input type="submit" value="Send ChatMessage"></input></div>
       </form>
     </body>
   </html>
   """)
# END: MainPage    
# START: PostHandler
def post(self):
    chatter = self.request.get(u"name")
    msg = self.request.get(u"message")
    global Messages
    Messages.append(ChatMessage(chatter, msg))
    # Now that we've added the message to the chat, we'll redirect
    # to the root page, which will make the user's browser refresh to
    # show the chat including their new message.
    self.redirect('/')        
# END: PostHandler




# START: Frame
chatapp = webapp.WSGIApplication([('/', ChatRoomPage)])


def main():
run_wsgi_app(chatapp)

if __name__ == "__main__":
main()
# END: Frame

Не в состоянии обрабатывать все, что я пишу в приложении чата, когда оно работает. Он загружается, но как только я ввожу свое сообщение (даже используя только стандартные символы), я получаю

File "D:\Python25\lib\StringIO.py", line 270, in getvalue
self.buf += ''.join(self.buflist)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 64: ordinal not in       range(128) 

сообщение об ошибке. Другими словами, если я хочу использовать какие-либо символы в приложении, я не могу добавить неанглийские символы в свой интерфейс. Или наоборот, я могу использовать не-английские символы в приложении, только если я не кодирую файл в utf-8. Как заставить все это работать вместе?

Ответы [ 2 ]

2 голосов
/ 22 августа 2011

Ваши строки содержат символы Unicode, но это не строки Unicode, а строки байтов.Вам нужно добавить к каждому префикс u (как в u"foo"), чтобы превратить их в строки Unicode.Если вы убедитесь, что все ваши строки являются строками Unicode, вы должны устранить эту ошибку.

Вы должны также указать кодировку в заголовке Content-Type, а не в метатеге, например:

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

Обратите внимание, что ваша жизнь была бы намного проще, если бы вы использовали систему шаблонов вместо написания HTML-кода внутри вашего кода Python.

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

@ Томас К. Спасибо за ваше руководство здесь. Благодаря вам я смог придумать, может быть, - как вы сказали, - маленькое решение о нарушении - так что кредит за ответ должен пойти вам Следующая строка кода:

Messages.append(ChatMessage(chatter, msg))

Должно выглядеть так:

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

По сути, мне нужно закодировать всю строку utf-8 в ascii.

...