簡體   English   中英

UnicodeEncodeError: 'ascii' 編解碼器無法在打印功能中編碼字符

[英]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將編碼strsys.stdout.encoding sys.stdout.encoding默認為locale.getpreferredencoding返回的 這通常是您的 linux 用戶的LANG環境變量。

解決方案

如果我們假設您的程序沒有覆蓋正常的編碼行為,那么應該通過確保代碼由 Python3 解釋器在 UTF-8 語言環境中執行來解決問題。

  • 100%確定代碼正在由 Python3 解釋器執行 - 從程序中打印sys.version_info
  • 運行腳本時嘗試設置PYTHONIOENCODING環境變量: PYTHONIOENCODING=UTF-8 python3 myscript.py
  • 使用終端中的locale命令(或echo $LANG )檢查您的語言locale 如果它不是以UTF-8結尾,請考慮更改它。 如果您使用的是公司計算機,請咨詢您的系統管理員。
  • 如果您的代碼在 cron 作業中運行,請記住,cron 作業通常使用 'C' 或 'POSIX' 語言環境運行 - 這可能使用 ASCII 編碼 - 除非明確設置了語言環境。 同樣,如果腳本在不同的用戶下運行,請檢查他們的區域設置。

解決方法

如果更改環境不可行,您可以通過使用錯誤處理程序編碼為 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

忽略替換處理程序會丟失信息 - 您無法判斷哪個字符已被空格或問號替換。

xmlcharrefreplacenamereplace處理程序不會丟失信息,但替換序列可能會降低文本對人類的可讀性。

由您決定哪種權衡對於您的程序輸出的使用者來說是可以接受的。

如果您決定使用替換處理程序,您可以像這樣更改代碼:

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.

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