[英]UnicodeEncodeError: 'ascii' codec can't encode character […]
[英]UnicodeEncodeError: 'ascii' codec can't encode character in print function
我的公司正在使用一個數據庫,我正在編寫一個與該數據庫交互的腳本。 已經有一個腳本用於將查詢放在數據庫上,並基於該腳本將從數據庫返回結果的查詢。
我正在 unix 環境中工作,我在腳本中使用該腳本從數據庫中獲取一些數據,並將查詢結果重定向到文件。 現在,當我嘗試讀取此文件時,我收到一條錯誤消息:
UnicodeEncodeError: 'ascii' codec can't encode character '\u2013' in position 9741: ordinal not in range(128)
我知道由於文件的編碼,python 無法讀取文件。 文件的編碼不是 ascii,這就是錯誤出現的原因。 我嘗試檢查文件的編碼並嘗試使用自己的編碼讀取文件。
我使用的代碼是-
os.system("Query.pl \"select title from bug where (ste='KGF-A' AND ( status = 'Not_Approved')) \">patchlet.txt")
encoding_dict3={}
encoding_dict3=chardet.detect(open("patchlet.txt", "rb").read())
print(encoding_dict3)
# Open the patchlet.txt file for storing the last part of titles for latest ACF in a list
with codecs.open("patchlet.txt",encoding='{}'.format(encoding_dict3['encoding'])) as csvFile
readCSV = csv.reader(csvFile,delimiter=":")
for row in readCSV:
if len(row)!=0:
if len(row) > 1:
j=len(row)-1
patchlets_in_latest.append(row[j])
elif len(row) ==1:
patchlets_in_latest.append(row[0])
patchlets_in_latest_list=[]
# calling the strip_list_noempty function for removing newline and whitespace characters
patchlets_in_latest_list=strip_list_noempty(patchlets_in_latest)
# coverting list of titles in set to remove any duplicate entry if present
patchlets_in_latest_set= set(patchlets_in_latest_list)
# Finding duplicate entries in list
duplicates_in_latest=[k for k,v in Counter(patchlets_in_latest_list).items() if v>1]
# Printing imp info for logs
print("list of titles of patchlets in latest list are : ")
for i in patchlets_in_latest_list:
**print(str(i))**
print("No of patchlets in latest list are : {}".format(str(len(patchlets_in_latest_list))))
其中 Query.pl 是為從數據庫中引入查詢結果而編寫的 perl 腳本。我為“patchlet.txt”(用於存儲來自 HSD 的結果的文件)獲得的編碼是:
{'encoding': 'Windows-1252', 'confidence': 0.73, 'language': ''}
即使我為讀取文件提供了相同的編碼,我也會收到錯誤消息。
請幫助我解決此錯誤。
編輯:我正在使用 python3.6
編輯2:
在輸出結果時,我收到錯誤消息,文件中有一行包含一些未知字符。 該行看起來像:
一些失敗,因為 vtrace 不能與一些跟蹤一起使用。
我正在使用 gvim,在 gvim 中,“vtrace”看起來像“~Vvtrace”。 然后我手動檢查了數據庫中的這個字符,字符是“-”,根據我的鍵盤,它既不是連字符也不是下划線。這些類型的字符造成了問題。
我也在 linux 環境中工作。
編輯 3:我添加了更多有助於跟蹤錯誤的代碼。 此外,我還突出顯示了出現錯誤的“打印”語句(print(str(i)))
。
問題
根據問題中的信息,程序正在處理非 ASCII 輸入數據,但無法輸出非 ASCII 數據。
具體來說,這段代碼:
for i in patchlets_in_latest_list:
print(str(i))
導致此異常:
UnicodeEncodeError: 'ascii' 編解碼器無法編碼字符 '\–'
這種行為在 Python2 中很常見,其中在unicode
對象上調用str
會導致 Python 嘗試將對象編碼為 ASCII,如果對象包含非 ASCII 字符,則會導致UnicodeEncodeError
。
在 Python3 中,在str
實例上調用str
不會觸發任何編碼。 然而調用print
上的功能str
將編碼str
到sys.stdout.encoding
。 sys.stdout.encoding
默認為locale.getpreferredencoding返回的值。 這通常是您的 linux 用戶的LANG
環境變量。
解決方案
如果我們假設您的程序沒有覆蓋正常的編碼行為,那么應該通過確保代碼由 Python3 解釋器在 UTF-8 語言環境中執行來解決問題。
sys.version_info
。PYTHONIOENCODING=UTF-8 python3 myscript.py
locale
命令(或echo $LANG
)檢查您的語言locale
。 如果它不是以UTF-8
結尾,請考慮更改它。 如果您使用的是公司計算機,請咨詢您的系統管理員。解決方法
如果更改環境不可行,您可以通過使用錯誤處理程序編碼為 ASCII,然后解碼回str
來解決 Python 中的問題。
在您的特定情況下有四個有用的錯誤處理程序,它們的效果用以下代碼演示:
>>> s = 'Hello \u2013 World'
>>> s
'Hello – World'
>>> handlers = ['ignore', 'replace', 'xmlcharrefreplace', 'namereplace']
>>> print(str(s))
Hello – World
>>> for h in handlers:
... print(f'Handler: {h}:', s.encode('ascii', errors=h).decode('ascii'))
...
Handler: ignore: Hello World
Handler: replace: Hello ? World
Handler: xmlcharrefreplace: Hello – World
Handler: namereplace: Hello \N{EN DASH} World
忽略和替換處理程序會丟失信息 - 您無法判斷哪個字符已被空格或問號替換。
xmlcharrefreplace和namereplace處理程序不會丟失信息,但替換序列可能會降低文本對人類的可讀性。
由您決定哪種權衡對於您的程序輸出的使用者來說是可以接受的。
如果您決定使用替換處理程序,您可以像這樣更改代碼:
for i in patchlets_in_latest_list:
replaced = i.encode('ascii', errors='replace').decode('ascii')
print(replaced)
無論您在哪里打印可能包含非 ASCII 字符的數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.