2013-06-28 20 views
1

我现在在Ubuntu 13.04和Python 2.7.4上,并试图运行包含以下行的脚本:ascii编解码器无法解码位于Ubuntu/Python中的位置错误中的字节0xe3,但无法在OS X/Python上解码

html = unicode(html, 'cp932').encode('utf-8') 
html1, html2 = html.split(some_text) # this line spits out the error 

但是,当我在Ubuntu 13.04上运行上述脚本时,它发现错误UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 106: ordinal not in range(128)。但是,这个完全相同的脚本总是可以在OS X 10.8和Python 2.7.3上成功执行。所以我想知道为什么错误只发生在两个平台之一...

我首先想到的是,特别是在看完这篇文章后(UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 1)是因为我处于不同的LANG环境,我在OS X上使用jp_JP.UTF-8,但在Ubuntu上使用en_US.UTF-8。所以我也试着在上面提到的脚本中再增加一行os.environ['LANG'] = 'jp_JP.UTF-8',但是仍然有同样的错误。

另一个奇怪的现象是,当我尝试从Ubuntu的IPython shell中运行脚本并在错误发生后立即进入调试模式,然后运行最初触发错误的行时,我没有错误更多...

那么这里发生了什么?我错过了什么?

在此先感谢。

+0

'some_text'中有什么?我的猜测是它是一个“unicode”对象,而不是“str”。如果是这样,该行将有效地调用'unicode(html).split(some_text)',而这种隐式转换就是失败的地方。你能记录每个平台上的类型和字节并看看吗? – abarnert

+0

另外,您链接的问题与您的问题无关。正如接受的答案所说,用户的问题不是关于他的代码中的编码和解码,而是关于当他向终端打印时发生的隐式编码。你不会在任何地方(或者至少不在这条线上)这么做,所以它不会影响你。 (并且,即使它的确如此,你的两个语言环境都使用UTF-8,所以这不会成为问题。) – abarnert

+0

PS,你为什么使用'unicode(html,'cp932')。encode('utf -8' )'?混合和匹配两种不同的转换方式并不违法,但这绝对是奇怪的。为什么不'html.decode('cp932')。encode('utf-8')'? – abarnert

回答

1

你还没有给我们足够的信息可以肯定的,但有一个很好的机会,这是你的问题:

如果some_textunicode对象,那么这行:

html1, html2 = html.split(some_text) # this line spits out the error 

...在str上调用split,并传递unicode参数。每当在相同的调用中混合使用strunicode时,Python 2.x会通过在str上自动调用unicode来处理该问题。所以,这就是等价于:

html1, html2 = unicode(html).split(some_text) # this line spits out the error 

...这相当于:

html1, html2 = html.decode(sys.getdefaultencoding()).split(some_text) # this line spits out the error 

...如果有任何非ASCII字符html,这将无法完全按照你所看到的。


简单的解决方法是显式编码some_text为UTF-8:

html1, html2 = html.split(some_text.encode('utf-8')) 

不过,我个人甚至不会尝试与str对象来自3个不同的字符集都在同一个程序中工作。为什么不只是decode/encode在非常边缘,只处理unicode到处都是对象?

+0

正如你所提到的,我确认'html'是'str','some_text'是'unicode'对象。在阅读你的评论,特别是'sys.getdefaultencoding()'后,我发现OS X和Ubuntu的工作原理是不同的,因为我把'sitecustomize.py'设置为OS X上的默认编码为utf-8,但是不在Ubuntu上。而且我在Ubuntu上也放置了相同的文件,然后脚本成功运行。为了您的信息'html'由urllib2.urlopen()。read()产生,我不知道它返回一个'str'类型。非常感谢。非常感谢。 – Blaszard

+0

@ user2360798:如果他们没有另外说明,Python 2.x中的大部分内容都会返回一个'str'。但即使在3.x中,大多数情况下返回的是Unicode对象,“urlopen”仍然会返回字节,否则它将不得不猜测编码。你下载的资源不太可能使用你的默认编码,而且考虑到所有的编码方式都可以被指定(HTTP标头,HTML头部分,根本不......),它实际上是无法猜测的,所以它留给你。 – abarnert

相关问题