Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python没有';不能正确解释UTF8_Python_Django_Unicode_Utf 8 - Fatal编程技术网

Python没有';不能正确解释UTF8

Python没有';不能正确解释UTF8,python,django,unicode,utf-8,Python,Django,Unicode,Utf 8,我知道类似的问题已经被问过无数次了,但是尽管读了很多,我还是找不到一个适合我的情况的解决方案 我有一个django应用程序,我在其中创建了一个管理脚本。这个脚本读取一些文本文件,并将它们输出到终端(稍后它将对内容做更多有用的事情,但我仍在测试),字符以转义序列出现,如\xc3\xa5,而不是预期的å。由于转义序列意味着Ã¥,这是由于编码问题而对å的常见误解,因此我怀疑至少有两个地方出现了错误。然而,我不知道在哪里-我已经检查了我能想到的所有可能的罪犯: 终端编码为UTF-8echo$LANG给

我知道类似的问题已经被问过无数次了,但是尽管读了很多,我还是找不到一个适合我的情况的解决方案

我有一个django应用程序,我在其中创建了一个管理脚本。这个脚本读取一些文本文件,并将它们输出到终端(稍后它将对内容做更多有用的事情,但我仍在测试),字符以转义序列出现,如
\xc3\xa5
,而不是预期的
å
。由于转义序列意味着
Ã¥
,这是由于编码问题而对
å
的常见误解,因此我怀疑至少有两个地方出现了错误。然而,我不知道在哪里-我已经检查了我能想到的所有可能的罪犯:

  • 终端编码为UTF-8<代码>echo$LANG给出了
    en_US.UTF-8
  • 文本文件以UTF-8编码<代码>文件*在它们所在的目录中会导致所有条目都列为“UTF-8 Unicode文本”,但不包含任何非ASCII字符且列为“ASCII文本”的条目除外。在该文件上运行
    iconv-f ascii-t utf8 thefile.txt>utf8.txt
    将生成另一个使用ascii文本编码的文件
  • Python脚本都是UTF-8(或者,在某些情况下,是不带非ASCII字符的ASCII)。我尝试在我的管理脚本中插入带有一些特殊字符的注释,以强制将其另存为UTF-8,但没有改变行为。上述对文本文件的观察也适用于所有Python脚本文件
  • 处理文本文件的Python脚本顶部有
    #-*-编码:utf-8-*-
    ;前面唯一一行是
    #/usr/bin/python3
    ,但我已经尝试将python2.7更改为
    ../python
    ,或者完全删除它,让Django决定,但没有结果
  • 根据“Django本机支持Unicode数据”,因此我可以在应用程序中的任何位置“安全地传递Unicode字符串”
我真的想不出还有什么地方可以在链中寻找非UTF-8链接。我在哪里可能错过了换成UTF-8的设置

为了完整性:我正在使用
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
    抱怨
    \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
为了完整性:我使用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)))