我正在尝试在python 2.7.2中处理unicode。我知道有.encode('utf-8')
的东西,但是我添加它的时间是1/2,我得到错误,而且当我不添加它时,我得到错误的时间减半。
有没有办法告诉python - 我认为是最新的&现代语言只是使用字符串的unicode而不是让我不得不放弃.encode('utf-8')
的东西吗?
我知道... python 3.0应该这样做,但我不能使用3.0和2.7并不是那么老了...
例如:
url = "http://en.wikipedia.org//w/api.php?action=query&list=search&format=json&srlimit=" + str(items) + "&srsearch=" + urllib2.quote(title.encode('utf-8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 19: ordinal not in range(128)
更新
如果我从我的所有代码中删除所有.encode
语句并将# -*- coding: utf-8 -*-
添加到我的文件顶部,就在#!/usr/bin/python
下面,然后我得到以下内容,就像我没有完全添加# -*- coding: utf-8 -*-
。
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py:1250: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
return ''.join(map(quoter, s))
Traceback (most recent call last):
File "classes.py", line 583, in <module>
wiki.getPage(title)
File "classes.py", line 146, in getPage
url = "http://en.wikipedia.org/w/api.php?action=query&prop=revisions&format=json&rvprop=content&rvlimit=1&titles=" + urllib2.quote(title)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 1250, in quote
return ''.join(map(quoter, s))
KeyError: u'\xf1'
我不是手动输入任何字符串,我从网站解析HTML和json。因此脚本/字节流/无论它们是什么,都是由python创建的。
更新2 我可以移动错误,但它会不断出现在新的地方。我希望python会是一个有用的脚本工具,但看起来好像没有运气3天后我会尝试不同的语言。很遗憾,在osx上预装了python。我已经标记了修正我发布的错误的一个实例的答案。
答案 0 :(得分:19)
这是一个非常古老的问题,但只是想添加一个部分建议。虽然我同情OP的痛苦 - 我自己也经历了很多 - 这是让事情变得“更容易”的一个(部分)答案。把它放在任何Python 2.7脚本的顶部:
from __future__ import unicode_literals
这至少可以确保您自己的文字字符串默认为unicode而不是str。
答案 1 :(得分:17)
除了在任何地方使用unicode字符串并立即解码您收到的任何编码字符串之外,没有办法使unicode“正常工作”。问题是,无论您是处理编码数据还是未编码数据,还是使用能够为您跟踪数据的工具,或者您将度过一段美好时光,您都必须保持直线。
Python 2做了一些有问题的事情:它使str
为“默认”而非unicode
等字符串文字之类的东西,它默默地将str
强制转换为{{1}当你添加两个时,它允许你在已经编码的字符串上调用unicode
来对其进行双重编码。因此,有很多python编码器和python库不知道他们设计的编码是什么,但仍然设计用于处理某些特定编码,因为{ {1}}类型旨在让程序员自己管理编码。每次使用这些库时都必须考虑编码,因为它们本身不支持.encode()
类型。
在您的特定情况下,第一个错误告诉您正在处理编码的UTF-8数据并尝试对其进行双重编码,而第二个错误则告诉您正在处理未编码的数据。 看起来就像你可能同时拥有它们一样。你应该找到并解决问题的根源(我怀疑它与我上面提到的无声强制有关),但这是一个应该在短期内修复它的黑客:
str
如果这实际上是一个无声强制的情况,你应该能够使用优秀的unicode-nazi工具轻松追踪问题:
unicode
这将在unicode泄漏到非unicode字符串的时候给你回溯,而不是尝试从实际问题中排除这种异常方式。有关详细信息,请参阅此related question的答案。
答案 2 :(得分:3)
是的,将您的unicode数据定义为unicode文字:
>>> u'Hi, this is unicode: üæ'
u'Hi, this is unicode: üæ'
您通常希望使用'\ uxxxx` unicode转义或设置源代码编码。例如,模块顶部的以下行将编码设置为UTF-8:
# -*- coding: utf-8 -*-
阅读Python Unicode HOWTO以获取详细信息,例如默认编码等(默认源代码编码,例如ASCII)。
至于你的具体例子,你的标题不是Unicode文字,而是python字节字符串,而python正试图将它解码为到 unicode,这样你就可以再次编码了。这失败了,因为这种自动编码的默认编解码器是ASCII:
>>> 'å'.encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
编码仅适用于实际的unicode字符串,因此字节字符串需要显式解码:
>>> 'å'.decode('utf-8').encode('utf-8')
'\xc3\xa5'
如果您习惯使用Python 3,那么Python 2中的unicode文字(u''
)是Python 3中的新默认字符串类型,而Python 2中的常规(字节)字符串(''
)与Python 3中的bytes
对象(b''
)相同。
如果title
上有和没有编码调用都有错误,则表示您有混合数据。测试标题并根据需要进行编码:
if isinstance(title, unicode):
title = title.encode('utf-8')
您可能想知道产生混合unicode /字节字符串标题的原因,并纠正该源以始终产生一个或另一个。
答案 3 :(得分:2)
确保title.encode(“utf-8”)中的标题是unicode的类型,不要使用str(“İŞşĞğÖöÜü”)
在你的字符串中使用unicode(“ĞğıIİiÖöŞşcçÇ”)
答案 4 :(得分:2)
实际上,使用unicode实现Python的最简单方法是使用Python 3,默认情况下一切都是unicode。
不幸的是,没有很多为P3编写的库,以及编码和编写的一些基本差异。关键字使用。这就是我遇到的问题:我需要的库仅适用于P 2.7,我不知道将它们转换为P 3. :(