簡體   English   中英

UnicodeEncodeError:'ascii'編解碼器無法編碼字符u'\\ xa3'

[英]UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3'

我有一個Excel電子表格,我正在閱讀其中包含一些£符號。

當我嘗試使用xlrd模塊讀取它時,我收到以下錯誤:

x = table.cell_value(row, col)
x = x.decode("ISO-8859-1")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 0: ordinal not in range(128)

如果我將其重寫為x.encode('utf-8'),它會停止拋出錯誤,但不幸的是,當我將數據寫入其他地方時(如latin-1),£符號都變得亂碼。

我該如何解決這個問題,並正確閱讀英鎊符號?

---更新---

某些讀者建議我根本不需要解碼它,或者我可以在需要時將其編碼為Latin-1。 這個問題是我最終需要將數據寫入CSV文件,它似乎反對原始字符串。

如果我根本不對數據進行編碼或解碼,則會發生這種情況(在我將字符串添加到名為items的數組之后):

for item in items:
    #item = [x.encode('latin-1') for x in item]
    cleancsv.writerow(item)
File "clean_up_barnet.py", line 104, in <module>
 cleancsv.writerow(item)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2022' in position 43: ordinal not in range(128)

即使我取消注釋Latin-1行,我也會得到相同的錯誤。

圍繞所有“'ascii'編解碼器無法編碼字符...”的一個非常簡單的方法csvwriter的問題是使用unicodecsv ,csvwriter的替代品。

使用pip安裝unicodecsv然后你可以以完全相同的方式使用它,例如:

import unicodecsv
file = open('users.csv', 'w')
w = unicodecsv.writer(file)
for user in User.objects.all().values_list('first_name', 'last_name', 'email', 'last_login'):
    w.writerow(user)

值得的是:我是xlrd的作者。

xlrd產生unicode嗎?
選項1:閱讀xlrd doc第一xlrd底部的Unicode部分: 該模塊將所有文本字符串顯示為Python unicode對象。
選項2: print type(text), repr(text)

你說“”如果我把它重寫為x.encode('utf-8')它就會停止拋出一個錯誤,但不幸的是當我把數據寫到其他地方時(如latin-1),£符號都變成了當然,如果你把UTF-8編碼的文本寫入一個期望latin1的設備,它將會出現亂碼。 你有什么期望?

你在你的編輯中說:“”“即使我取消注釋Latin-1行”“”我也會得到同樣的錯誤。 這是非常不可能的 - 更有可能的是你在不同的源代碼行(未注釋的latin1行而不是writerow行)中出現了稍微不同的錯誤(提到latin1編解碼器而不是ascii編解碼器)。 仔細閱讀錯誤消息有助於理解。

你的問題是,一般來說你的數據不能用latin1編碼; 現實世界的數據很少。 你的POUND SIGN可以在latin1中編碼,但這不是你所有的非ASCII數據。 有問題的角色是U + 2022 BULLET,在latin1中無法編碼。

如果你cp1252提到過你在Mac OS X上工作,那么它會幫助你更快地得到更好的答案...對於適合CSV的編碼的通常懷疑是cp1252 (Windows),而不是mac-roman

你的代碼片段說的是x.decode ,但是你得到了一個編碼錯誤 - 意思是x已經是Unicode了,所以,為了“解碼”它,它必須首先變成一個字節串(這就是默認的編解碼器ansi出現並失敗)。 在你的文本,然后你說:“如果我重寫OT對x。 編碼 ” ......這似乎意味着,你知道 X是Unicode。

那么你正在做什么 - 以及你的意思是做什么 - 編碼unicode x來獲得一個編碼的字節串,或者將一串字節解碼成一個unicode對象?

我發現很遺憾你可以在一個字節字符串上調用encode ,並在一個unicode對象上decode ,因為我發現它似乎引導用戶除了混亂......但至少在這種情況下你似乎設法傳播混亂(至少對我來說;-)。

如果看起來x是unicode,那么你永遠不想“解碼”它 - 你可能想要對它進行編碼以獲得帶有某個編解碼器的字節串,例如latin-1,如果這是你需要的某種類型I / O目的(對於您自己的內部程序使用,我建議始終堅持使用unicode - 只有在您絕對需要接收編碼字節字符串時才進行編碼/解碼以進行輸入/輸出)。

x = x.decode("ISO-8859-1")
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 0: ordinal not in range(128)

仔細觀察:你有一個Unicode ***編碼***錯誤調用解碼方法。

其原因是decode旨在從字節序列( str )轉換為unicode對象。 但是,正如約翰所說, xlrd已經使用了Unicode字符串,因此x已經是一個unicode對象。

在這種情況下,Python的2.x的假定你的意思是解碼str對象,因此它“有益”為您創建一個。 但是為了將unicode轉換為str ,它需要編碼,並選擇ASCII,因為它是字符編碼的最小公分母。 您的代碼有效地被解釋為

x = x.encode('ascii').decode("ISO-8859-1")

失敗,因為x包含非ASCII字符。

由於x已經是unicode對象,因此不需要decode 但是,現在您遇到了Python 2.x csv模塊不支持Unicode的問題。 您必須將數據轉換為str對象。

for item in items:
    item = [x.encode('latin-1') for x in item]
    cleancsv.writerow(item)

這是正確的,除了你的數據中有字符(U + 2022 BULLET),而Latin-1不能代表它。 有幾種方法可以解決這個問題:

  • x.encode('latin-1', 'ignore')刪除子彈(或其他非Latin-1字符)。
  • x.encode('latin-1', 'replace')用問號替換子彈。
  • 用拉丁字符1替換子彈,如*·
  • 使用的字符編碼, 包含所有你需要的字符。

目前,UTF-8得到廣泛支持,因此幾乎沒有理由對文本文件使用任何其他編碼。

xlrd與Unicode一起使用,因此您獲取的字符串是Unicode字符串。 £ - 符號的代碼點為U + 00A3,因此所述字符串的表示應為u'\\xa3' 這已被正確讀入; 它是您在整個程序中應該使用的字符串。

在某處編寫此(抽象,Unicode)字符串時,需要選擇編碼。 那時候,你應該.encode它編碼成那個編碼,比如latin-1


>>> book = xlrd.open_workbook( "test.xls" )
>>> sh = book.sheet_by_index( 0 )
>>> x = sh.cell_value( 0, 0 )
>>> x
u'\xa3'
>>> print x
£

# sample outputs (for e.g. writing to a file)
>>> x.encode( "latin-1" )
'\xa3'
>>> x.encode( "utf-8" )
'\xc2\xa3'

# garbage, because x is already Unicode
>>> x.decode( "ascii" )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa3' in position 0:
ordinal not in range(128)
>>>

使用xlrd,我有一行... xl_data.find(str(cell_value))...它給出錯誤:“'ascii'編解碼器不能編碼位置3中的字符u'\\ xdf':序數不是在范圍(128)“。 論壇中的所有建議對我的德語單詞都沒用。 但改成:... xl_data.find(cell.value)...沒有錯誤。 因此,我認為在某些命令中使用字符串作為參數,xldr具有特定的編碼問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM