u''前缀和unicode()有什么区别?
1 2 3 4
| # -*- coding: utf-8 -*-
print u'上午' # this works
print unicode('上午', errors='ignore') # this works but print out nothing
print unicode('上午') # error |
对于第三个print,错误显示:unicodedecodeerror:'ascii'编解码器无法在位置0处解码字节0xe4。
如果我有一个包含非ASCII字符的文本文件,例如"下午",如何正确读取和打印它?
- stackoverflow.com/questions/761361/…
- 你在编辑中添加的问题有点胡说八道。您的"\x97"字节的编码是什么?无论你的答案是什么,用它作为对unicode或str.decode的争论,而不是"utf-8"。正如JoelSpolsky在MartijnPieters链接的帖子中所写:"不知道字符串使用什么编码是没有意义的。"
因此,您使用不同类型的文字表示法创建了一个字节字符串对象,然后尝试将其转换为unicode()对象,但失败的原因是str->unicode转换的默认编解码器是ASCII。
这两种动物完全不同。如果要使用后者,则需要为其提供显式编解码器:
1
| print unicode('上午', 'utf8') |
两者的关联方式与使用0xFF和int('0xFF', 0)的关联方式相同;前者使用十六进制表示法定义值255的整数,后者使用int()函数从字符串中提取整数。
另一种方法是使用str.decode()方法:
1
| print '上午'.decode('utf8') |
不要试图使用错误处理程序(如ignore'或'replace'),除非您知道自己在做什么。例如,'ignore'特别可以通过选择错误的编解码器来掩盖潜在的问题。
您可能需要阅读关于python和unicode的内容:
- 谢谢您。它起作用了。但是,我尝试阅读一个包含非ASCII字符的文本文件,比如"下午"。对于文件的每一行,我使用Unicode(行"utf8"),它显示的错误与问题描述中所述的相同。
- @德恒业:也许你的文件使用了不同的编解码器?不要用unicode()来解码每一行。您可以使用import io,然后使用io.open(filename, encoding='utf8')(或其他编解码器)让python在您阅读时为您解码文件内容。
- 我遇到了新问题。你能看到我的新编辑吗?谢谢您。@马蒂尼派
- @德恒业:请不要在你现在的职位上提出新的问题,用新的职位来解决这个问题。无法转换该字节,因为它不是UTF-8。你有一个不同的编解码器,你必须弄清楚你有什么数据。不要尝试将其解码为UTF-8。
当str在Python 2.7.x中没有前缀u''时,解释器看到的是一个没有显式编码的字节字符串。
如果在执行unicode()时不告诉解释器如何处理这些字节,则(如您所见)默认为尝试decode通过ASCII编码方案所看到的字节。
这是将str的普通字节转换为unicode对象的初步步骤。
使用ascii到decode意味着:尝试用硬编码映射解释str的每个字节,该映射是0和127之间的一个数字。
您遇到的错误类似于dictKeyError:解释器遇到了一个字节,该字节的ascii编码方案没有指定的映射。
因为解释器不知道如何处理字节,所以它抛出了一个错误。
您可以通过使用另一组编码/解码映射(一组超出ASCII的映射,如UTF-8)将字节告知decode,来更改这一初步步骤,如其他答案中所述。
如果解释器在所选方案中为str中的每个字节(或字节)找到一个映射,它将成功解码,解释器将使用生成的映射生成unicode对象。
python unicode对象是一系列Unicode代码点。Unicode代码空间中有1112064个有效代码点。
如果您选择的解码方案是对文本(或代码点)进行编码的方案,那么打印时的输出应该与原始文本相同。
也可以考虑尝试Python 3。相关差异在下面的第一个注释中解释。
- python 3不默认字符串为utf-8,相反,str是unicode文本(一系列unicode代码点),类似于2.x unicode类型。如果不使用编码声明(在python 3和iso 8859-1 pre-2.5之前是ASCII),那么python3中的默认utf8引用源文件编码。
- 谢谢您。编辑。
请尝试:"下午"。解码("utf8","忽略")。编码("utf8")
- 你想详细说明一下吗?谢谢您。
- 我试过了,当我读到一个包含非ASCII码的文件时,这实际上是有效的。所以我赞成。
- 为什么要附加编码?当然,'byte str literal'.decode('source codec')会和unicode('byte str literal', 'source codec')做同样的事情。
- @dehengye:这是因为'ignore'错误处理程序将导致任何输入工作。这并不意味着你有可用的文本。
- 为什么要"忽略"?这就掩盖了任何问题,如果输入实际上不是UTF-8呢?
- @马提尼彼得斯非常感谢你的奉献。
- @dehengye:假设您的输入文件使用了gbk编解码器,那么使用line.decode('utf8', 'ignore')会给您一个结果,但不会有任何有用的结果。由于编码字符串中的所有字节都不是有效的UTF-8字节,因此u'上午'.encode('gbk').decode('utf8', 'ignore')为您提供了一个空字符串,因此在解码时它们都被忽略。但是,gbk是中文文本最常用的编解码器之一。
unicode是一个对象类型,而"u"是用于表示该对象是unicode对象的文字。它类似于用来表示long int的"l"字面值。
- 除了L前缀不需要创建一个长整型int,如果你的字面是>sys.maxint,并且long(123)没有做一个翻译步骤,可以用一个额外的参数来调节。
- 此外,对于除索引操作和某些C调用之外的所有操作,长整型和规则整型都是完全相同的。