2011-05-18 40 views
6

在我的數據庫中,我存儲了一些UTF-8字符。例如。在「名稱」「α」字段Python UTF-8轉換問題

通過Django的ORM,當我讀了這一點,我得到的東西像

>>> p.name 
u'\xce\xb1' 
>>> print p.name 
α 

我所期待的「α」。

一些挖後,我想,如果我這樣做

>>> a = 'α' 
>>> a 
'\xce\xb1' 

所以當Python是試圖顯示「\ XCE \ XB1」我得到的α,但是當它試圖顯示U「\ XCE \ XB1」 ,它是雙重編碼?

爲什麼我首先得到u'\ xce \ xb1'?有沒有辦法讓我回到'\ xce \ xb1'?

謝謝。我的UTF-8和unicode處理知識確實需要一些幫助...

+2

你真的把UTF-8存儲到數據庫嗎?這不太好...... – 2011-05-18 20:39:47

+0

你會得到一個包含字節串的Unicode字符。什麼地方是錯誤的 - 你編碼它,然後存儲在一個Unicode字段?如果你需要返回值,'p.name..encode(「iso-8859-1」)。decode(「utf-8」)'應該這樣做,但它並不能真正解決問題。 – 2011-05-18 20:57:48

+0

@ IgnacioVazquez-Abrams嗨,如果您有時間回答,當您需要將UTF-8編碼的unicode符號存儲到數據庫時,您還有什麼其他選擇? – 2016-11-25 12:33:31

回答

2

嘗試在您的字符串之前放置Unicode字符uu'YOUR_ALFA_CHAR'並修改你的數據庫編碼,因爲Django總是支持UTF-8。

+1

聽起來很棒,如果它是OP正在討論的字符串字面值,但我認爲它來自數據庫的方式。 – 2011-05-18 20:46:35

+0

它來自數據庫,我沒有把我自己的字符串文字。當我使用mysql命令行工具查看數據庫時,我看到了alpha。編碼是utf8,但是當我在Python中加載時,我得到了u'\ xce \ xb1',而不是'\ xce \ xb1'。 – OverClocked 2011-05-18 20:49:58

0

嘗試使用p.name.encode('latin-1')轉換編碼。這裏有一個演示:

>>> print u'\xce\xb1' 
α 
>>> print u'\xce\xb1'.encode('latin-1') 
α 
>>> print '\xce\xb1' 
α 
>>> '\xce\xb1' == u'\xce\xb1'.encode('latin1') 
True 

欲瞭解更多信息,請參閱str.encodeStandard Encodings

+0

我得到'\ xc3 \ x8e \ xc2 \ xb1',來自u'\ xce \ xb1' – OverClocked 2011-05-18 20:55:34

+0

哼哼 - 嘗試'latin-1'中的編碼。我希望那些作品! 'p.encode'('utf-8')'可能會打印「α」;它不應該打印你的字符串。字符串編碼是一個非常善變的野獸! :o) – 2011-05-18 21:02:10

0

你可以通過解碼功能使任何字節序列轉換爲內部Unicode表示:

print '\xce\xb1'.decode('utf-8') 

這可以讓你從各種數據源的一個字節序列,然後把它變成一個Python unicode字符串。

參考:http://docs.python.org/library/stdtypes.html#string-methods

+0

問題是打印u'\ xce \ xb1'.decode('utf-8'),而不是打印'\ xce \ xb1'.decode('utf-8') – OverClocked 2011-05-18 20:54:43

1

的問題是,p.name未正確存放和/或從數據庫中讀出。

Unicode小字母是U + 03B1,p.name應該打印爲u'\ x03b1',或者如果您使用的是支持Unicode的終端,則實際的字母符號本身可能已經打印在引號中。請注意u'\ xce \ xb1'和u'\ xceb1'之間的區別。前者是雙字符串,後者是單字符串。我不知道UTF-8的'03'字節是如何翻譯成'CE'的。

2

你似乎有一個UTF-8編碼字符串的單個字節解釋爲unicode碼點。你可以在「解碼」的串出這種奇怪的形式與:

p.name = ''.join(chr(ord(x)) for x in p.name) 

或許

p.name = ''.join(chr(ord(x)) for x in p.name).decode('utf8') 

一個辦法讓你的字符串「編碼」成這種形式是

''.join(unichr(ord(x)) for x in '\xce\xb1') 

雖然我有一種感覺,你的字符串實際上是由你的系統的不同組件在這種狀態下使用的編碼不同意的。

您可能需要修復不良「編碼」的來源,而不是僅修復當前數據庫中的數據。上面的代碼可能會將您的不良數據轉換一次,但我建議您不要將此代碼插入到Django應用程序中。

+0

一個非常好的和詳細的解釋。 – 2016-11-25 12:36:41

+0

你能解釋一下,爲什麼chr(ord(x)將工作如果x> 255,因爲「chr(x):返回一個ASCII碼是整數i的字符的字符串..參數必須在[0 .255],如果我在該範圍之外,則會引發ValueError。「 – 2016-11-25 12:56:08