[問題] unicode->bytes->unicode的編碼
想讓 python2 跟 python3 的程式交換資料,但在 unicode 這部分遇到點麻煩
請問有沒有 codec 能符合下列條件?
1. 能將字元範圍從 \u0000 ~ \uFFFF 的 unicode 字串轉成 bytes 再轉回 unicode
且不會出錯或遺失資料
2. 在 python2 和 python3 下,同樣的 unicode 字串編碼後得到的 bytes 結果相同
3. 在 python2 和 python3 下,同樣的 bytes 解碼後得到的 unicode 結果相同
4. 速度快且編碼後的 bytes 體積小
舉例來說,u'\ud800\udc00' 這段字串因為不是合法的 unicode
編解碼上就會出現各種奇怪的問題,不曉得有沒有解?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.46.145.28
推
09/26 00:27, , 1F
09/26 00:27, 1F
utf32 不行耶...
python2
>>> u'\ud800\udc00'.encode('utf32')
'\xff\xfe\x00\x00\x00\x00\x01\x00'
python3
>>> u'\ud800\udc00'.encode('utf32')
b'\xff\xfe\x00\x00\x00\xd8\x00\x00\x00\xdc\x00\x00'
推
09/26 00:45, , 2F
09/26 00:45, 2F
應該是字元寬度的關係,windows python2 預設 ucs2,python3 則是 ucs4
推
09/26 00:49, , 3F
09/26 00:49, 3F
→
09/26 00:51, , 4F
09/26 00:51, 4F
→
09/26 00:55, , 5F
09/26 00:55, 5F
推
09/26 00:56, , 6F
09/26 00:56, 6F
→
09/26 00:57, , 7F
09/26 00:57, 7F
所以很難搞...基本上那轉換結果也不能說錯,可是就會出現
s.encode('utf-8').decode('utf-8') != s 這種不直覺的東西
→
09/26 00:58, , 8F
09/26 00:58, 8F
→
09/26 01:00, , 9F
09/26 01:00, 9F
土炮有效能問題,自從用了 python,就再也沒再裝過 c++ 了 XD
目前是 utf-7 頂著用,他們似乎不認為 utf-7 編的是文字所以沒擋 surrogate
不過遇到像上面舉的那個例子一樣會爆炸 orz...
推
09/26 01:12, , 10F
09/26 01:12, 10F
→
09/26 01:12, , 11F
09/26 01:12, 11F
這個一樣有可能會出現不直覺的結果
python3
>>> s = u'\ud800\udc00'
>>> s.encode('unicode_internal')
b'\x00\xd8\x00\xdc'
>>> s.encode('unicode_internal').decode('unicode_internal')
'\U00010000\x27'
>>> s.encode('unicode_internal').decode('unicode_internal') == s
False
推
09/26 01:31, , 12F
09/26 01:31, 12F
其實跟 OS 沒啥關係啦...
→
09/26 10:49, , 13F
09/26 10:49, 13F
→
09/26 10:50, , 14F
09/26 10:50, 14F
→
09/26 10:50, , 15F
09/26 10:50, 15F
是要拿來傳輸沒錯,想要在 python3 使用一些只有 python2 才有的 module
pickle 在 python2 跟 python3 本來就不通用啊
→
09/26 14:36, , 16F
09/26 14:36, 16F
→
09/26 14:36, , 17F
09/26 14:36, 17F
雖然官方文件那樣寫,但實際上並沒那麼美好
像是 datetime.datetime 這種內建物件就不相容
上面舉例的 u'\ud800\udc00' 這種不合法字串也不相容
我問這個問題就是要用在自己寫的 pickle 裡面的 XD
→
09/26 18:04, , 18F
09/26 18:04, 18F
→
09/27 19:16, , 19F
09/27 19:16, 19F
很遺憾,還是不行耶...
→
09/28 09:09, , 20F
09/28 09:09, 20F
在 python2 跟 python3 底下,這本來就都沒問題呀
>>> s = u'\ud800\udc00'
>>> s == u'\ud800\udc00'
True
→
09/28 09:10, , 21F
09/28 09:10, 21F
不准是指?如果是指不能 encode,那是因為某些編碼(如 utf-8)有檔 surrogates
※ 編輯: os653 來自: 114.46.115.224 (09/28 19:15)
→
09/28 20:39, , 22F
09/28 20:39, 22F
→
09/28 20:39, , 23F
09/28 20:39, 23F
Python 近期熱門文章
PTT數位生活區 即時熱門文章