pythonstring编码/解码

这里是我的错误信息的尝试。 我究竟做错了什么?

string.decode("ascii", "ignore") 

UnicodeEncodeError:'ascii'编解码器不能对位置37的字符u'\ xa0'进行编码:序号不在范围内(128)

 string.encode('utf-8', "ignore") 

UnicodeDecodeError:'ascii'编解码器无法解码位置37中的字节0xc2:序号不在范围内(128)

你不能解码一个unicode ,你不能编码一个str 。 试着以相反的方式去做。

猜测在原始问题中遗漏的所有东西,但是,假设Python 2.x的关键是仔细阅读错误信息:尤其是在你称之为“编码”的地方,但是信息说“解码”,反之亦然,而且包含在消息中的值的types。

在第一个示例中, stringunicodetypes的,并且您试图对其进行解码,这是将字节string转换 unicode的操作。 Python有用地尝试使用默认的“ascii”编码将unicode的值转换为str ,但由于您的string包含一个非ascii字符,所以您得到的错误是Python无法编码 unicode值。 这是一个显示inputstringtypes的例子:

 >>> u"\xa0".decode("ascii", "ignore") Traceback (most recent call last): File "<pyshell#7>", line 1, in <module> u"\xa0".decode("ascii", "ignore") UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 0: ordinal not in range(128) 

在第二种情况下,您将尝试对字节string进行编码。 编码是一种将unicode转换为字节string的操作,所以Python首先尝试将字节string转换为unicode,并且由于您没有给asciistring,默认ascii解码器会失败:

 >>> "\xc2".encode("ascii", "ignore") Traceback (most recent call last): File "<pyshell#6>", line 1, in <module> "\xc2".encode("ascii", "ignore") UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128) 

除了获得decode和向后encode ,我认为这里的一部分答案实际上是不使用ascii编码 。 这可能不是你想要的。

首先,想像一个纯文本文件一样。 这只是一堆没有实际附加编码的字节。 它是如何被解释的,取决于任何一段代码正在阅读它。 如果您不知道本段的内容,请阅读Joel的“绝对最低限度每个软件开发人员”,绝对地,积极地了解Unicode和字符集 。

当然,我们都知道所造成的混乱。 答案是,至less在内存中,对所有string都有一个标准的编码。 这就是unicode进来的地方。我无法确切地跟踪Python在内部使用的编码方式,但这并不重要。 重点是你知道这是一个字节序列的解释以某种方式。 所以你只需要考虑字符本身,而不是字节。

问题是,在实践中,你遇到了两个。 有些图书馆会给你一些信息,有些图书馆会期待一些。 无论什么时候stream式传输一系列字节(例如到磁盘或从磁盘请求或通过Web请求),这当然都是有意义的。 所以你需要能够来回翻译。

inputcodecs :这是这两种数据types之间的翻译库。 您使用encode从文本string( unicode )生成一个字节序列( str ),并使用decode从字符序列( str )中获取文本string( unicode )。

例如:

 >>> s = "I look like a string, but I'm actually a sequence of bytes. \xe2\x9d\xa4" >>> codecs.decode(s, 'utf-8') u"I look like a string, but I'm actually a sequence of bytes. \u2764" 

这里发生了什么? 我给了Python一个字节序列,然后我告诉它,“给我这个unicode版本,因为这个字节序列在'utf-8' 。 它按照我的要求做了,那些字节( 一个心脏字符 )现在被当作一个整体来处理,用Unicode代码表示。

让我们走另一条路:

 >>> u = u"I'm a string! Really! \u2764" >>> codecs.encode(u, 'utf-8') "I'm a string! Really! \xe2\x9d\xa4" 

我给Python一个Unicodestring,并要求它使用'utf-8'编码将string转换为一个字节序列。 所以它做了,现在心脏只是一堆字节,它不能打印为ASCII; 所以它显示我hex。

当然,我们也可以使用其他编码。

 >>> s = "I have a section \xa7" >>> codecs.decode(s, 'latin1') u'I have a section \xa7' >>> codecs.decode(s, 'latin1')[-1] == u'\u00A7' True >>> u = u"I have a section \u00a7" >>> u u'I have a section \xa7' >>> codecs.encode(u, 'latin1') 'I have a section \xa7' 

'\xa7'是Unicode和Latin-1中的部分字符 。)

所以对于你的问题,你首先需要弄清楚你的str是什么编码。

  • 它来自一个文件吗? 从networking请求? 从你的数据库? 然后源决定编码。 找出源的编码并使用它将其翻译成unicode

     s = [get from external source] u = codecs.decode(s, 'utf-8') # Replace utf-8 with the actual input encoding 
  • 或者,也许你正试图写出来的地方。 目的地期望的编码是什么? 用它来把它翻译成str 。 对于纯文本文档,UTF-8是一个不错的select; 大多数东西都可以读取它。

     u = u'My string' s = codecs.encode(u, 'utf-8') # Replace utf-8 with the actual output encoding [Write s out somewhere] 
  • 你只是在内存中来回翻译互操作性或什么? 然后只需select一个编码,并坚持下去; 'utf-8'可能是最好的select:

     u = u'My string' s = codecs.encode(u, 'utf-8') newu = codecs.decode(s, 'utf-8') 

在现代编程中,你可能从来不想使用'ascii'编码。 这是所有可能的字符的一个非常小的子集,没有我知道的系统默认使用它或任何东西。

Python 3尽最大努力通过改变名称来使其变得非常清晰。 在Python 3中, str被replace为bytesunicode被replace为str

这是因为你的inputstring不能根据编码规则进行转换(默认是严格的)。

我不知道,但我总是使用直接unicode()构造函数编码,至less这是在官方文档的方式:

 unicode(your_str, errors="ignore")