Google Datastore中的UTF-8 Python问题

1 投票
1 回答
625 浏览
提问于 2025-04-17 01:30

我在这些论坛上到处问关于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的Datastore。我使用的书中的代码(《云中的代码》)看起来是这样的(我省略了多余的部分):

#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)

当然,我在文件中声明了(# -- coding: utf-8 --)语句,并放了:

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

但这并没有缓解问题。

如你所见,我对Python不是很熟悉,编码/解码的问题对我来说有点新鲜。我希望能得到你的帮助。如果有人能告诉我在这个情况下我哪里出错了,以及将来应该使用什么方法来避免类似的问题,我将非常感激。谢谢你们!

1 个回答

3

encode 是把 Unicode 转换成字节,而 decode 是把字节转换回 Unicode。你需要小心不要把这两者搞混。你的错误可能意味着:

  1. chattermsgtext 已经是字节了,而你还在尝试对它进行编码。Python 2 的一个最糟糕的“特性”就是它允许你这样做——它会先用 ASCII(最简单的编码方式)尝试解码这些字节,然后再用你要求的方式重新编码。这在 Python 3 中已经修复了,但在 App Engine 上你不能使用 Python 3。

  2. App Engine 期望存储的是 Unicode(确实如此)。所以你需要传给它一个 Unicode 字符串,而不是进行编码。实际上,如果你的数据已经是字节字符串,你需要先 解码 它,才能存储。

简而言之,首先要尝试的就是在存储数据之前,不要 调用 .encode

(我可能之前提到过这个,但如果没有,请花时间阅读 这篇关于 Unicode 的文章

撰写回答