Python没有';不能正确解释UTF8
我知道类似的问题已经被问过无数次了,但是尽管读了很多,我还是找不到一个适合我的情况的解决方案 我有一个django应用程序,我在其中创建了一个管理脚本。这个脚本读取一些文本文件,并将它们输出到终端(稍后它将对内容做更多有用的事情,但我仍在测试),字符以转义序列出现,如Python没有';不能正确解释UTF8,python,django,unicode,utf-8,Python,Django,Unicode,Utf 8,我知道类似的问题已经被问过无数次了,但是尽管读了很多,我还是找不到一个适合我的情况的解决方案 我有一个django应用程序,我在其中创建了一个管理脚本。这个脚本读取一些文本文件,并将它们输出到终端(稍后它将对内容做更多有用的事情,但我仍在测试),字符以转义序列出现,如\xc3\xa5,而不是预期的å。由于转义序列意味着Ã¥,这是由于编码问题而对å的常见误解,因此我怀疑至少有两个地方出现了错误。然而,我不知道在哪里-我已经检查了我能想到的所有可能的罪犯: 终端编码为UTF-8echo$LANG给
\xc3\xa5
,而不是预期的å
。由于转义序列意味着Ã¥
,这是由于编码问题而对å
的常见误解,因此我怀疑至少有两个地方出现了错误。然而,我不知道在哪里-我已经检查了我能想到的所有可能的罪犯:
- 终端编码为UTF-8<代码>echo$LANG给出了
en_US.UTF-8
- 文本文件以UTF-8编码<代码>文件*在它们所在的目录中会导致所有条目都列为“UTF-8 Unicode文本”,但不包含任何非ASCII字符且列为“ASCII文本”的条目除外。在该文件上运行
将生成另一个使用ascii文本编码的文件iconv-f ascii-t utf8 thefile.txt>utf8.txt
- Python脚本都是UTF-8(或者,在某些情况下,是不带非ASCII字符的ASCII)。我尝试在我的管理脚本中插入带有一些特殊字符的注释,以强制将其另存为UTF-8,但没有改变行为。上述对文本文件的观察也适用于所有Python脚本文件
- 处理文本文件的Python脚本顶部有
;前面唯一一行是#-*-编码:utf-8-*-
,但我已经尝试将python2.7更改为#/usr/bin/python3
,或者完全删除它,让Django决定,但没有结果../python
- 根据“Django本机支持Unicode数据”,因此我可以在应用程序中的任何位置“安全地传递Unicode字符串”
lines=file.readlines()
读取文件,并使用标准的print()
函数进行打印。在任何一端都不会发生手动编码或解码
更新:
针对评论中的停顿:
为所有文件生成打印(sys.getdefaultencoding(),sys.stdout.encoding,f.encoding)
('ascii','UTF-8',无)
- 我开始编译一个SSCCE,很快就发现问题只存在于我试图打印元组中的值时。换句话说,
工作正常,但print(行[0].strip())
工作不正常。添加print(行[0].strip()、行[1].strip())
会产生一个元组,其中两个字符串都用前缀.decode('utf-8')
和u
(正确的\xe5
转义序列)标记,而不是前面的奇数字符-但我不知道如何将它们作为常规字符串打印,没有转义字符。我已经测试了另一个对
的调用,以及在.decode('utf-8')
中的包装,但都失败了str()
抱怨unicodeincodeerror
不能用ascii编码。由于单个字符串工作正常,我不知道还要测试什么\xe5
# -*- 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
为了完整性:我使用lines=file.readlines()读取文件,并使用标准print()函数打印。在任何一端都不会发生手动编码或解码
在Python3.x中,标准的print
函数只将Unicode写入sys.stdout
。因为这是一个io.TextIOWrapper
,所以它的write
方法相当于:
self.wrapped_binary_file.write(s.encode(self.encoding, self.errors))
所以一个可能的问题是sys.stdout.encoding
与终端的实际编码不匹配
当然,另一个原因是shell的编码与终端窗口的编码不匹配 例如,在OS X上,我创建了一个myscript.py,如下所示:
print('\u00e5')
print '({}, {})'.format(lines[0].strip(), lines[1].strip())
print '({})'.format(', '.join(element.encode('utf-8') for element in my_tuple)))
然后我启动Terminal.app,创建一个编码为“Western(ISO Latin 1)”的会话配置文件,用该会话配置文件创建一个选项卡,然后执行以下操作:
$ export LANG=en_US.UTF-8
$ python3 myscript.py
…我完全了解您所看到的行为。从您的评论中可以看出,您使用的是python-2,而不是python-3 如果您使用的是python-3,那么有必要阅读上一篇文章来了解python正在做什么 编码的基本流程是: 从编码解码到unicode->处理->从unicode编码到编码 在python3中,字节被解码为字符串,字符串被编码为字节。 字节到字符串的解码由
open()
为您处理
[..]内置的open()函数可以返回一个类似文件的对象
假定文件内容采用指定的编码,并接受
read()和write()等方法的Unicode参数。这很有效
通过open()的编码和错误参数[…]
因此,要从utf-8编码文件中读取unicode,您应该执行以下操作:
# python-3
with open('utf8.txt', mode='r', encoding='utf-8') as f:
lines = f.readlines() # returns unicode
如果希望使用python-2实现类似的功能,可以使用:
这里最大的问题是,您将Python2和Python3混为一谈。特别是,您已经编写了Python3代码,并且正在尝试在Python2.7中运行它。但在此过程中还存在一些其他问题。所以,让我试着解释所有出错的地方
我开始编译一个SSCCE,很快就发现问题只存在于我试图打印元组中的值时。换句话说,
print(行[0].strip())
工作正常,但print(行[0].strip()、行[1].strip())
工作不正常
这里的第一个问题是元组(或任何其他元组)的str
print tuple(map(str, my_tuple))
print '({})'.format(', '.join(map(str, my_tuple)))
sys.stdio.wrapped_binary_file.write(s.encode(sys.stdio.encoding, sys.stdio.errors))
sys.stdio.write(s.encode(sys.getdefaultencoding()))
print '({})'.format(', '.join(element.encode('utf-8') for element in my_tuple)))