Last Updated on 2021-10-12 by Clay
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-5: truncated \UXXXXXXXX escape
SyntaxError 是 Python 中一個表示『語法錯誤』的訊息、 unicodeescape 指的是 Unicode 編碼的跳脫字元 (escape) 。這樣一來,是不是比較好理解上面這個錯誤訊息了呢?沒錯,那就是你在 Python 中出現了關於 Unicode 編碼的 SyntaxError (語法錯誤)!
但是不要緊張,這種類型錯誤在 Python 中是很容易不小心發生的。發生的原因通常是誤用了 \
字元在字串中。
因為在 Python 當中, \
是代表著『跳脫字元』(escape)、或者你習慣說是用於『轉義』的字元。通常這個符號是用來代表著接在斜線後方的符號真的是一個文字或是一個符號,而非其他程式中所特有的意思。
只看文字很難理解,下面直接看個實際案例。
使用案例
通常我們會在哪裡使用到跳脫字元呢?以下來看個經典案例:
print('It's a nice day.')
看起來似乎我們希望印出
It's a nice day.
對吧?然而實際上,這行程式碼是會報錯的。原因非常簡單。
在 Python 中,我們可以使用 print('xxx') 這樣的表達方式將我們想要印出的 xxx 當作字串印出;但是在字串當中,倘若又遇到了 ' 符號,Python 的直譯器便會搞不懂我們到底哪裡才是真正的字串,然後就會發生錯誤。
要解決這個問題,我們便得在字串中的 ' 符號前加上跳脫字元 "\" 來讓其轉義,代表這是真正的符號,而非字串的上標。
print('It\'s a nice day.')
Output:
It's a nice day.
可以看到,成功印出了我們想要的字串了。
那麼,文章一開始提到的報錯又是為什麼呢?以下我再提一個我遇到的例子。
有一天,我在 Linux 系統的伺服器執行程式、進行實驗。為了將實驗數據保存成 CSV 檔案格式、並可以在 Windows 的作業系統上正常檢視,我選擇直接在檔案的開頭寫入 "\uFEFF" 這樣的編碼。
這是所謂的 "BOM" (Byte Order Mark),是 Unicode 裡頭為了向系統說明此檔案的資料屬於『Big-Ending』型態。
然後,是的,我就得到了以下這個報錯。
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-5: truncated \UXXXXXXXX escape
就如同文章開頭所述,這個報錯是因為 "\" 這個斜線的符號在 Python 中代表著的是『跳脫字元』(escape)。
解決方法
既然是轉義失敗,那麼最簡單的解決方法,便是不要讓其『轉義』。
方法一: 在字串前方加上 "r"
title = r'\uFFEF'
在 Python 中,字串的最前方加上 r,代表的是這是一個完整的字串,所有文字都是符號,不會有其他意思。
這是一個可能的做法。
方法二: 將 "\" 改成 "/" (Windows)
在 Windows 作業系統上,可以嘗試將 "\" 符號修改為 "/" 符號,比方說將以下這樣的程式:
open("C:\Users\Clay\Desktop\test.txt")
修改為:
open("C:/Users/Clay/Desktop/test.txt")
這也是一個可能的方法。
方法三: 將 "\" 符號轉義
比方說將下面的程式碼:
open("C:\Users\Clay\Desktop\test.txt")
修改為:
open("C:\\Users\\Clay\\Desktop\\test.txt")
如此一來,就如同上方解釋所說, "\" 這個符號的意思本來便是『轉義』,所以將自己 "\" 轉義為真正的符號,或許程式也就能正常運作了。
以上是三種常見的解決方法。如此一來,程式多半就不會再出現這個報錯,實測在 Windows 上也可以正常運行。
References
- https://stackoverflow.com/questions/37400974/unicode-error-unicodeescape-codec-cant-decode-bytes-in-position-2-3-trunca
- https://community.alteryx.com/t5/Alteryx-Designer-Discussions/Error-unicodeescape-codec-can-t-decode-bytes/td-p/427540