我知道类似的问题已经被问过一百万次了,但是尽管阅读了很多问题,我还是找不到适合我情况的解决方案。
我有一个 django 应用程序,我在其中创建了一个管理脚本。该脚本读取一些文本文件,并将它们输出到终端(稍后它将对内容做更多有用的事情,但我仍在对其进行测试)并且字符以转义序列出现,\xc3\xa5
而不是预期的å
. 由于该转义序列意味着Ã¥
,这是å
由于编码问题而导致的常见误解,我怀疑至少有两个地方出错了。但是,我不知道在哪里 - 我已经检查了我能想到的所有可能的罪魁祸首:
- 终端编码为UTF-8;
echo $LANG
给en_US.UTF-8
- 文本文件以 UTF-8 编码;
file *
在它们所在的目录中,所有条目都被列为“UTF-8 Unicode 文本”,除了一个不包含任何非 ASCII 字符并被列为“ASCII 文本”的条目。iconv -f ascii -t utf8 thefile.txt > utf8.txt
在该文件上运行会产生另一个具有 ASCII 文本编码的文件。 - Python 脚本都是 UTF-8(或者,在某些情况下,是没有非 ASCII 字符的 ASCII)。我尝试在我的管理脚本中插入带有一些特殊字符的注释,以强制它保存为 UTF-8,但它并没有改变行为。以上对文本文件的观察也适用于所有 Python 脚本文件。
- 处理文本文件的 Python 脚本
# -*- encoding: utf-8 -*-
位于顶部;前面的唯一一行是#!/usr/bin/python3
,但我尝试过更改.../python
为 Python 2.7 或完全删除它以将其留给 Django,但没有结果。 - 根据文档,“Django 原生支持 Unicode 数据”,因此我“可以在应用程序的任何位置安全地传递 Unicode 字符串”。
我真的想不出其他地方可以在链中寻找非 UTF-8 链接。我在哪里可能错过了更改为 UTF-8 的设置?
为了完整起见:我正在使用标准功能读取文件lines = file.readlines()
并打印。print()
两端都不会发生手动编码或解码。
更新:
针对评论中的提问:
print(sys.getdefaultencoding(), sys.stdout.encoding, f.encoding)
产生('ascii', 'UTF-8', None)
所有文件。- 我开始编译一个 SSCCE,很快发现问题只有在我尝试打印元组中的值时才会出现。换句话说,
print(lines[0].strip())
工作正常,但print(lines[0].strip(), lines[1].strip())
没有。添加.decode('utf-8')
会产生一个元组,其中两个字符串都标有前置u
和\xe5
(正确的转义序列å
)而不是之前的奇数字符 - 但我不知道如何将它们打印为常规字符串,没有转义字符。我已经测试了另一个调用.decode('utf-8')
以及包装,str()
但都失败了,因为UnicodeEncodeError
抱怨\xe5
不能用 ascii 编码。由于单个字符串可以正常工作,我不知道还要测试什么。
SSCCE:
# -*- coding: utf-8 -*-
import os, sys
for root,dirs,files in os.walk('txt-songs'):
for filename in files:
with open(os.path.join(root,filename)) as f:
print(sys.getdefaultencoding(), sys.stdout.encoding, f.encoding)
lines = f.readlines()
print(lines[0].strip()) # works
print(lines[0].strip(), lines[1].strip()) # does not work