【发布时间】:2013-02-13 11:11:47
【问题描述】:
为了对 URI 进行编码,我使用了urllib.quote("schönefeld"),但是当字符串中存在一些非 ascii 字符时,它会触发
KeyError: u'\xe9'
Code: return ''.join(map(quoter, s))
我的输入字符串是köln, brønshøj, schönefeld 等
当我尝试在 windows 中打印语句时(使用 python2.7,pyscripter IDE)。但是在 linux 中它会引发异常(我猜平台无关紧要)。
这就是我正在尝试的:
from commands import getstatusoutput
queryParams = "schönefeld";
cmdString = "http://baseurl" + quote(queryParams)
print getstatusoutput(cmdString)
探究问题原因:
在urllib.quote() 中,实际上在return ''.join(map(quoter, s)) 处抛出异常。
urllib中的代码是:
def quote(s, safe='/'):
if not s:
if s is None:
raise TypeError('None object cannot be quoted')
return s
cachekey = (safe, always_safe)
try:
(quoter, safe) = _safe_quoters[cachekey]
except KeyError:
safe_map = _safe_map.copy()
safe_map.update([(c, c) for c in safe])
quoter = safe_map.__getitem__
safe = always_safe + safe
_safe_quoters[cachekey] = (quoter, safe)
if not s.rstrip(safe):
return s
return ''.join(map(quoter, s))
异常原因在''.join(map(quoter, s)),对于s中的每个元素,都会调用quoter函数,最后用''加入列表并返回。
对于非 ascii 字符 è,等效键将是 %E8,它出现在 _safe_map 变量中。但是当我调用quote('è') 时,它会搜索键\xe8。使key不存在并抛出异常。
所以,我只是在 try-except 块中调用 ''.join(map(quoter, s)) 之前修改了 s = [el.upper().replace("\\X","%") for el in s]。现在它工作正常。
但是我很烦我所做的是正确的方法还是会产生任何其他问题? 而且我确实有 200 多个 linux 实例,很难在所有实例中部署此修复程序。
【问题讨论】:
-
这是带有 unicode 值的 Python 2 吗?它适用于已经编码的数据。
-
您确实不会收到
urllib.quote('sch\xe9nefeld')的错误。您仅收到urllib.quote(u'sch\xe9nefeld')的错误(注意u''unicode 文字)。 -
@MartijnPieters 所以
cmdString = "http://baseurl" + quote("schönefeld")这应该像cmdString=u"http://baseurl"+quote(u"schönefeld")? -
不,你误会我了。我声明该错误仅在您提供
quote()unicode 值时发生。对于字节字符串(已经编码),这不会发生。
标签: python unicode urllib2 urlencode urllib