编码错误的一个非常常见的来源是,当您将字符串与unicode
一起添加时,它将默默地将字符串强制转换为unicode
。这可能会导致混合编码问题,并且可能很难调试。
例如:
import urllib
import webbrowser
name = raw_input("What's your name?\nName: ")
greeting = "Hello, %s" % name
if name == "John":
greeting += u' (Feliz cumplea\xf1os!)'
webbrowser.open('http://lmgtf\x79.com?q=' + urllib.quote_plus(greeting))
如果输入“John”,将失败并出现神秘错误:
/usr/lib/python2.7/urllib.py:1268: UnicodeWarning: Unicode equal comparison faile
d to convert both arguments to Unicode - interpreting them as being unequal
return ''.join(map(quoter, s))
Traceback (most recent call last):
File "feliz.py", line 7, in <module>
webbrowser.open('http://lmgtf\x79.com?q=' + urllib.quote_plus(greeting))
File "/usr/lib/python2.7/urllib.py", line 1273, in quote_plus
s = quote(s, safe + ' ')
File "/usr/lib/python2.7/urllib.py", line 1268, in quote
return ''.join(map(quoter, s))
KeyError: u'\xf1'
特别难以追查实际错误发生在实际强制发生的路上的时间。
如果将字符串强制转换为unicode,如何配置python立即发出警告或异常?
答案 0 :(得分:4)
在提出这个问题后,我做了一些研究并找到了完美的答案。 Armin Ronacher创造了一个名为unicode-nazi的精彩小工具。只需安装它并运行你的程序:
python -Werror -municodenazi myprog.py
你可以在强制发生的地方得到追溯:
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "SITE-PACKAGES/unicodenazi.py", line 128, in <module>
main()
File "SITE-PACKAGES/unicodenazi.py", line 119, in main
execfile(sys.argv[0], main_mod.__dict__)
File "myprog.py", line 4, in <module>
print foo()
File "myprog.py", line 2, in foo
return 'bar' + u'baz'
File "SITE-PACKAGES/unicodenazi.py", line 34, in warning_decode
stacklevel=2)
UnicodeWarning: Implicit conversion of str to unicode
如果您正在处理自己触发隐式强制的python库,并且您无法捕获异常或以其他方式解决它们,您可以省略-Werror
:
python -municodenazi myprog.py
并且至少看到stderr发生时会发出警告:
/SITE-PACKAGES/unicodenazi.py:119: UnicodeWarning: Implicit conversion of str to unicode
execfile(sys.argv[0], main_mod.__dict__)
barbaz
答案 1 :(得分:0)
这个错误根本不是神秘的。我可以从中收集urllib.quote()
(由quote_plus()
调用)并不能很好地处理unicode。一些快速的谷歌搜索,我发现this previous SO question要求unicode安全的替代品。不幸的是,似乎都不存在。