社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

使用utf-8字符串写入文件时出现python编解码器错误

JDM • 5 年前 • 1567 次点击  

我正在开发一个python 3 tkinter应用程序(os是windows 10),其总体功能包括以下详细信息:

  1. 读取一些文本文件,其中可能包含ascii、cp1252、utf-8或任何其他编码形式的数据

  2. 在“预览窗口”(tkinter label小部件)中显示这些文件的内容。

  3. 将文件内容写入单个输出文件(每次打开时追加)

对于1:我通过以二进制模式打开和读取文件,使文件读取编码不可知。为了将数据转换成字符串,我使用了一个循环,该循环遍历“可能”编码的列表,并依次尝试每个编码(使用 error='strict' )直到它碰到一个没有抛出异常的。这很管用。

for 2:一旦我得到解码的字符串,我就调用 set() Tkinter标签的方法 textvariable . 这也是可行的。

对于3:我以通常的方式打开一个输出文件,并调用 write() 方法来写入解码字符串。当字符串被解码为ascii或cp1252时,此操作有效,但当字符串被解码为utf-8时,它会引发异常:

'charmap' codec can't encode characters in position 0-3: character maps to <undefined>

我四处搜索,发现了一些类似的问题,但似乎没有解决这个具体问题。一些更复杂的问题限制了我的解决方案:

a.我可以回避这个问题,只需将读入的数据保留为字节,并将输出文件作为二进制文件打开/写入,但这会使一些输入文件内容无法读取。

B.虽然这个应用程序主要是针对Python3的,但我正在尝试使它与Python2交叉兼容——我们有一些慢/晚的采用者将使用它。(顺便说一下,当我在python 2上运行这个应用程序时,它也会抛出异常,但是对于cp1252数据和utf-8数据都会抛出异常。)


为了说明这个问题,我创建了这个精简的测试脚本。(我真正的应用程序是一个大得多的项目,而且它也是我公司的专利——所以不会公开发布!)

import tkinter as tk
import codecs

#Root window
root = tk.Tk()

#Widgets
ctrlViewFile1 = tk.StringVar()
ctrlViewFile2 = tk.StringVar()
ctrlViewFile3 = tk.StringVar()
lblViewFile1 = tk.Label(root, relief=tk.SUNKEN,
                        justify=tk.LEFT, anchor=tk.NW,
                        width=10, height=3,
                        textvariable=ctrlViewFile1)
lblViewFile2 = tk.Label(root, relief=tk.SUNKEN,
                        justify=tk.LEFT, anchor=tk.NW,
                        width=10, height=3,
                        textvariable=ctrlViewFile2)
lblViewFile3  = tk.Label(root, relief=tk.SUNKEN,
                         justify=tk.LEFT, anchor=tk.NW,
                         width=10, height=3,
                         textvariable=ctrlViewFile3)

#Layout
lblViewFile1.grid(row=0,column=0,padx=5,pady=5)
lblViewFile2.grid(row=1,column=0,padx=5,pady=5)
lblViewFile3.grid(row=2,column=0,padx=5,pady=5)

#Bytes read from "files" (ascii Az5, cp1252 European letters/punctuation, utf-8 Mandarin characters)
inBytes1 = b'\x41\x7a\x35'
inBytes2 = b'\xe0\xbf\xf6'
inBytes3 = b'\xef\xbb\xbf\xe6\x9c\xa8\xe5\x85\xb0\xe8\xbe\x9e'

#Decode
outString1 = codecs.decode(inBytes1,'ascii','strict')
outString2 = codecs.decode(inBytes2,'cp1252','strict')
outString3 = codecs.decode(inBytes3,'utf_8','strict')

#Assign stringvars
ctrlViewFile1.set(outString1)
ctrlViewFile2.set(outString2)
ctrlViewFile3.set(outString3)

#Write output files
try:
    with open('out1.txt','w') as outFile:
        outFile.write(outString1)
except Exception as e:
    print(inBytes1)
    print(str(e))

try:
    with open('out2.txt','w') as outFile:
        outFile.write(outString2)
except Exception as e:
    print(inBytes2)
    print(str(e))

try:
    with open('out3.txt','w') as outFile:
        outFile.write(outString3)
except Exception as e:
    print(inBytes3)
    print(str(e))

#Start GUI
tk.mainloop()
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/44113
 
1567 次点击  
文章 [ 2 ]  |  最新文章 5 年前