访问返回字典的键时,意外触发KeyError?
我有一个函数,它会生成并返回一个 _GET
字典,这个字典包含了URI查询字段中的键值对。假设这个URI是 http://127.0.0.1/path/to/query?foo=bar&bar=foo
,这个函数在一个派生的 BaseHTTPServer.BaseHTTPRequestHandler
中使用,出现了 KeyError
的情况:
class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Type", "text/plain")
self.end_headers()
_GET = query_parse(urlparse.urlparse(self.path).query)
# No KeyError here..
print "foo: %s\r\nbar: %s" % (GET["foo"], _GET["bar"])
# KeyError on _GET["foo"]..
self.wfile.write("foo: %s\r\nbar: %s\r\n" % (_GET["foo"], _GET["bar"]))
# Still KeyError on _GET["foo"] even if commenting above line
# and uncommenting below one!
#self.wfile.write("bar: %s\r\nfoo: %s\r\n" % (_GET["bar"], _GET["foo"]))
错误追踪信息:
localhost - - [19/Oct/2011 18:21:18] "GET /path/to/query?foo=bar&bar=foo HTTP/1.1" 200 -
localhost - - [19/Oct/2011 18:21:18] "GET /favicon.ico HTTP/1.1" 200 -
Traceback (most recent call last):
File "E:\Program\Python27\lib\SocketServer.py", line 284, in _handle_request_noblock
self.process_request(request, client_address)
File "E:\Program\Python27\lib\SocketServer.py", line 310, in process_request
self.finish_request(request, client_address)
File "E:\Program\Python27\lib\SocketServer.py", line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "E:\Program\Python27\lib\SocketServer.py", line 639, in __init__
self.handle()
File "E:\Program\Python27\lib\BaseHTTPServer.py", line 337, in handle
self.handle_one_request()
File "E:\Program\Python27\lib\BaseHTTPServer.py", line 325, in handle_one_request
method()
File "http-test.py", line 40, in do_GET
print "foo: %s" % _GET["foo"]
KeyError: 'foo'
2 个回答
0
与其使用query_parse(),不如直接用Python自带的查询解析器:
>>> s = 'http://127.0.0.1/path/to/query?foo=bar&bar=foo'
>>> t = urlparse.urlparse(s)
>>> urlparse.parse_qs(t.query)
{'foo': ['bar'], 'bar': ['foo']}
如果用pdb调试工具或者在代码里加一些打印语句,问题就会变得很容易发现。
1
我不知道你的 query_parse
函数是干什么的,但其实已经有一个现成的函数可以做到这一点,那就是 urlparse.parse_qs
:
>>> query = urlparse.urlparse('http://127.0.0.1/path/to/query?foo=bar&bar=foo').query
>>> urlparse.parse_qs(query)
{'bar': ['foo'], 'foo': ['bar']}
如果你不喜欢字典里的值是列表形式,你可以这样做:
>>> dict(urlparse.parse_qsl(query))
{'bar': 'foo', 'foo': 'bar'}
希望这些能帮到你。