谷歌应用引擎在StringProperty和StringListProperty对象中对Unicode的显示是否不同?
我有一个叫做 mRegion 的 db.StringProperty(),里面存的是一些韩文文本。在我的仪表板上,我能看到这个值是这样的:
한국 : 충청남도
但是,当我把这个字段放进一个字符串列表属性(db.StringListProperty())里时,结果变成了这样:
\ud55c\uad6d : \ucda9\uccad\ub0a8\ub3c4
我在客户端显示这个字符串列表属性的值时遇到了问题,这让我怀疑在服务器端存储这个值时是不是出了什么问题,因为我本来期待它能像 StringProperty 一样显示成可读的韩文。
有没有人知道我可能哪里出错了,或者这个第二种显示方式在字符串列表对象中是否正常,问题可能出在我的客户端?
谢谢。
更新一下问题的细节:我的客户端是一个 iPhone 应用。基本上,我用 iPhone 获取用户的 GPS 位置,然后通过反向地理编码 API 获取相关信息。我把这些信息发送到应用引擎并保存。这部分看起来是正常的,因为在韩国我能看到韩文字符。区域名称的获取过程大致是这样的:
region = self.request.get('region')
entry.init(region)
...
self.mRegion = region
这个过程很简单(而且有效)。
问题出现在我取回这些数据并发送回客户端的时候。总结一下:
query = db.GqlQuery("SELECT * FROM RegionData WHERE mLatitudeCenter >= :1 and mLatitudeCenter <= :2", latmin, latmax)
for entry in query:
output += entry.mRegion + ','
self.response.out.write(output)
当我把这些数据放到客户端的 UILabel 上时,它显示的是乱码。而且,当我把这个乱码的值再发送回服务器去查找区域时,它失败了。这让我觉得,可能不是发送的韩文文本,而是发送了一些其他的字符。如果你说这只是显示的问题,而不是数据本身的问题,那可能是我用来显示这些数据的系统字体出了问题?我曾经想过是不是在某个地方漏掉了正确的 encode() 或 decode() 调用,但不太确定。
1 个回答
很有可能,管理界面会以不同的方式显示这两者。后者明显是在做一个叫做repr(s)的操作,而前者只是简单地打印字符串。
不过,管理界面的显示方式并不会影响你的代码运行。无论是字符串(Strings)还是字符串列表(StringLists),它们在数据存储中都是以相同的方式存储的,返回给你的都是Unicode字符串,你可以根据自己的需要来处理这些字符串。
我强烈建议你阅读这篇关于Unicode的文章。简单来说,你需要处理两种东西:二进制数据和Unicode字符。为了让你困惑,Python把这两者都称为字符串——分别是“Unicode字符串”和“原始字符串”,但你只需要把前者当作真正的字符串来使用。
数据存储中有StringListProperty和StringProperty,它们存储和返回的都是Unicode字符串。你的框架也应该给你Unicode字符串,并且能接受Unicode字符串,但有些设计不好的框架可能做不到这一点。
你需要确保在处理文本的地方都在使用Unicode字符串,明确调用.encode()把Unicode字符串转换为原始字符串,调用.decode()把原始字符串转换为Unicode字符串,并且确保返回的响应的字符编码设置正确,同时你编码字符串时使用的是相同的编码方式。具体怎么做要看你的框架。
一旦你做到这些,如果还是有问题,我建议你写一些简单的单元测试——把数据存储到数据存储中,然后取出来并进行处理,最后检查它是否和你预期的一样——这样可以帮助你找到问题所在。