这个坑出在文件编码上。
当你使用 doc.writexml(f, encoding="utf-8")
时,这里的 encoding 只会在 xml 标签上添加encoding="utf-8"
标签,而 xml 文件内容本身的编码,是没有改变的。
这就意味着,如果你写入中文,无论你怎么 encode 、decode,最终只会得到一个充满乱码的 xml 文件。
正确的写法是这样:
with open(file, "w", encoding="utf-8") as f:
doc.writexml(file, encoding="utf-8")
在 open 方法里面加入 encoding="utf-8",才会改变文件的编码。
这个坑还没有人专门写,所以记录一下,希望能帮到一些人。
1
learningman 2020-08-17 11:47:43 +08:00
说明看文档要仔细
|
2
Jirajine 2020-08-17 11:51:34 +08:00 via Android
Python 的这个编码问题一直都很坑,别的大多数语言字符串都是 utf-8 encoded bytes,唯独 Python 的字符串是未编码的,而且编码时默认还是平台的编码而不是一律 utf-8 。
|
3
Nitroethane 2020-08-17 11:55:03 +08:00
这怕是你没仔细看文档吧,文档里清楚地写了 “For the Document node, an additional keyword argument encoding can be used to specify the encoding field of the XML header.”,人可没说是指定文件内容的编码
|
4
abersheeran 2020-08-17 12:59:17 +08:00
我个人觉得是你不懂 open 这个内置函数以及文件编码导致的。
|
5
abersheeran 2020-08-17 12:59:48 +08:00
@Jirajine 兄弟,这都 2020 年了,你还在这念 Python2 的经?
|
6
fhsan 2020-08-17 13:08:23 +08:00
都什么年代了,还分不清编码问题,python 获取当前操作系统编码,如果你想保持一致,write 、open 文本文件都要指定编码。统一编码是不可能的
|
7
Jirajine 2020-08-17 13:34:44 +08:00 via Android
@abersheeran 说的就是 Python3 啊,别的语言 string 可以直接当成 utf-8 encoded bytes 用,唯独 Python 需要额外把 string encode 成 bytes,并且默认参数在 Windows 下还不是 utf-8 。
至于内部如何表示那是另一回事了,string 暴露出来的接口就是未编码的字符串对象,需要调用 encode()才会变成 bytes 。 |
8
abersheeran 2020-08-17 19:47:48 +08:00
@Jirajine 你说的别的语言怕是 C 这种弱类型吧。哪个强类型语言还能把 string 当 bytes 用的?你举个例子。
|
9
Jirajine 2020-08-17 20:00:44 +08:00 via Android
@abersheeran golong 、rust 都是这样。
我上面的描述不太准确,不是把 string 当 bytes 用,而是 string 就是 utf-8 encoded bytes 。 因此把 string 往文件写不需要指定编码,string 就是二进制的 bytes,写二进制数据当然不需要指定编码。 |
10
abersheeran 2020-08-20 16:16:37 +08:00
@Jirajine Python3 的 str 不就是默认 utf8 的?往文件里写需要指定编码是因为默认使用你操作系统的编码打开的,因为你是中国人,win 选择中文,所以默认是 gbk 。但 Windows10 有强制 utf8 的选项,你要是不怕某些垃圾软件不兼容 utf8,你可以开开,就没这个问题了。
|