Python2与Python3字符编码兼容:ElementTree写入plist报错排查
解决Python3中ElementTree写入plist时的TypeError问题
这个问题本质是Python3对文本模式和二进制模式的严格区分导致的——Python2里str和bytes是混同的,所以你的代码能正常运行,但Python3里open('w')打开的是文本模式文件,只能写入str类型数据,而ElementTree的write()方法默认输出的是bytes,直接触发了类型错误。
下面给你两种可行的修正方案,选一种适合你的就行:
方案1:用文本模式写入(推荐)
这种方式更符合Python3的文本处理习惯,我们手动写入plist头部,然后让ElementTree输出字符串到文件:
import xml.etree.ElementTree as ET tree = ET.parse('com.input.plist') # 定义Apple plist要求的头部内容 plist_header = '''<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> ''' # 用文本模式打开文件,指定编码为utf-8 with open('com.new.plist', 'w', encoding='utf-8') as f: # 先写入头部字符串 f.write(plist_header) # 让ElementTree输出字符串,并且不自动生成xml声明(避免重复) tree.write(f, encoding='unicode', xml_declaration=False)
方案2:用二进制模式写入
如果更习惯处理字节流,可以用二进制模式打开文件,把所有内容转成bytes再写入:
import xml.etree.ElementTree as ET tree = ET.parse('com.input.plist') plist_header = '''<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> ''' # 二进制模式打开文件 with open('com.new.plist', 'wb') as f: # 把头部字符串转成utf-8编码的bytes写入 f.write(plist_header.encode('utf-8')) # ElementTree默认输出bytes,直接写入即可,同样关闭自动声明 tree.write(f, encoding='UTF-8', xml_declaration=False)
两种方案的核心都是:
- 避免重复生成xml声明(手动写了就不让ElementTree再写)
- 保证写入文件的内容类型和文件打开模式匹配(文本模式写str,二进制模式写bytes)
内容的提问来源于stack exchange,提问作者Elliott B
相关产品推荐
相关产品推荐

