2011-08-21 47 views
0

因此,在過去的幾天裏,我一直試圖在App Engine中學習Python。但是,我遇到了許多使用ASCII和UTF編碼的問題。最新鮮的問題如下:Google App Engine中的Python問題-UTF-8和ASCII

我有如下一段從書「代碼在雲」

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中顯示字符,我添加元標記 - 字符集= UTF-8「等

奇怪的是,如果輸入的是非標準字母,程序會很好地處理它們,並且不會顯示任何問題,但是如果我使用腳本輸入任何非ascii字母到web佈局,則無法加載。我發現添加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編碼文件時,我才能在應用程序中使用非英文字符。如何使它們一起工作?

+0

如果您尚未遇到它,請訪問unicode bootcamp:http://www.joelonsoftware.com/articles/Unicode.html。這對了解實際發生的事情至關重要。然後在StringIO文檔中查看關於unicode的警告:http://www.joelonsoftware.com/articles/Unicode.html –

+0

@Thomas K.我明白你的意思,並且我明白需要和使用不同的編碼。正如您在代碼的第二個示例中所見,我通過添加諸如# - * - coding:utf-8 - * - 或HTML charset元標記的行來解釋不同的字符集。我不明白的是Python如何處理這一切。爲什麼Python要求我不斷地對事物進行編碼和解碼,我自己呢?在這個例子中我如何完成它。我一直在用各種方法玩,包括(unicode(s,「utf-8」))和(.encode(「utf-8」),但很少成功。是的,我很缺乏經驗。 – Mathias

+0

我沒有確切地知道你的應用程序正在發生什麼,但是在第21行和第35行,嘗試讓你的字符串以'u'「」開頭,所以它們是unicode字符串。問題是你正在嘗試寫出一個混合的編碼字符串和unicode。 –

回答

2

您的字符串包含unicode字符,但它們不是unicode字符串,它們是字節字符串。您需要在每個字符前加上u(如u"foo")以使它們成爲unicode字符串。如果確保所有字符串都是Unicode字符串,則應該消除該錯誤。

你也應該指定在Content-Type頭的編碼,而不是meta標籤,就像這樣:

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

注意你的生活,如果你使用的不是與寫HTML內嵌模板系統將是一個容易得多你的Python代碼。

+0

謝謝。我會記住你的建議。 – Mathias

+0

@Mathias會發現他的生活會更容易,如果他至少使用Python 3做了'from __future__ import unicode_literals'。 He.encode(「UTF-8」)也是.encode(「UTF-8」)needs.encode(「UTF-8」)爲.encode(「UTF-8」)set.encode(「UTF-8」)將.encode(「UTF-8」)stream.encode(「UTF-8」)output.encode(「UTF-8」)encoding.encode(「UTF-8」)轉換爲.encode(「UTF-8」) avoid.encode(「UTF-8」)all.encode(「UTF-8」)this.encode(「UTF-8」)完全.encode(「UTF-8」)stupid.encode(「UTF-8」)廢話...編碼(「UTF-8」) – tchrist

+3

@tchrist這將是一個很好的建議,除了他使用App Engine,它不運行Python 3。 –

1

@Thomas K. 感謝您在這裏的指導。感謝你,我能夠想出,也許 - 正如你所說 - 一個小小的解決方案 - 所以答案的功勞應該歸功於你。下面的代碼行:

Messages.append(ChatMessage(chatter, msg)) 

應該是這樣的:

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

基本上我有編碼的所有UTF-8字符串ASCII。