【发布时间】:2011-08-21 14:21:51
【问题描述】:
所以在过去的几天里,我一直在尝试在 App Engine 中学习 Python。但是,我在 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" 等
奇怪的是,如果您输入非标准字母,程序会很好地处理它们,并毫无问题地显示它们。但是,如果我使用脚本在 Web 布局本身中输入任何非 ascii 字母,则无法加载。我发现添加 utf-8 编码行会起作用。所以我添加了(# -- coding: 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 对文件进行编码时,我才能在应用程序中使用非英文字符。如何让它们协同工作?
【问题讨论】:
-
如果你还没有遇到过,unicode bootcamp:joelonsoftware.com/articles/Unicode.html。这对于了解实际情况至关重要。然后查看 StringIO 文档中关于 unicode 的警告:joelonsoftware.com/articles/Unicode.html
-
@Thomas K。我明白你的意思,我理解不同编码的需要和使用。正如您在代码的第二个示例中看到的,我通过添加诸如 # -- coding: utf-8 -- 或 HTML 字符集元标记之类的行来解释不同的字符集。我不明白的是 Python 如何处理这一切。为什么 Python 要求我自己不断地来回编码和解码?我如何在这个例子中完成它。我一直在玩弄各种方法,包括 (unicode(s, "utf-8")) 和 (.encode("utf-8"),但收效甚微。是的,我很缺乏经验。
-
我不知道您的应用程序到底发生了什么,但是在第 21 和 35 行,尝试让您的字符串以
u"""开头,因此它们是 unicode 字符串。问题是你试图写出编码字符串和 unicode 的混合体。 -
@Thomas K。感谢您提供链接文章。这让我觉得我做错了事。 Messages.append(ChatMessage(chatter, msg)) 应该如下所示: Messages.append(ChatMessage(chatter.encode( "utf-8" ), msg.encode("utf-8" ))) 我会发布这是一个回答,但似乎我不能,至少 3 小时。
-
这行得通,但最好将它们存储为 unicode 字符串,并且仅在您调用
self.response.out.write时进行编码。
标签: python google-app-engine utf-8 ascii