从Python KeyError异常中获取键名

48

我想从Python的KeyError异常中获取键名:

例如:

myDict = {'key1':'value1'}
try:
    x1 = myDict['key1']
    x2 = myDict['key2'] 
except KeyError as e:
    # here i want to use the name of the key that was missing which is 'key2' in this example
    print error_msg[missing_key]

我已经尝试过这个了

print e
print e.args
print e.message

我的代码在Django视图中!

例如,如果我使用ipython并尝试e.arg或e.message,它可以正常工作。但是当我在Django视图中尝试时,我会得到以下结果:

"Key 'key2' not found in <QueryDict: {u'key1': [u'value']}>" 
("Key 'key2' not found in <QueryDict: {u'key1': [u'value']}>",) 
Key 'key2' not found in <QueryDict: {u'key1': [u'value']}>

虽然我只想要“key2”


这只是为了记录日志,还是您要实际使用这个键? - NPE
你可以看到,如果我使用 args[0],我会得到元组的第一个元素,这与我打印 e.message 时得到的相同。 - yossi
1
你使用的 Python 版本是哪个?在我的 Python 解释器中运行你的代码块时,当我打印异常时不会打印出那条长消息,只有键名(这也是所有答案都说的)。显然你的不同! - Jon Cairns
我使用Python 2.7,我认为它不同,因为我的代码在Django视图中。如果我使用IPython,我会得到与你们所有人相同的结果。 - yossi
你的系统上是否有多个版本的Python?如果是这样,iPython运行的版本是否与Django相同?(只是一个想法...) - GreenMatt
2
你展示的错误表明这是一个QueryDict,它是Django的构造,而不是普通的Python字典。不幸的是,我不熟悉Django,因此不知道来自QueryDict的KeyError是否会像Python字典一样行为; 这是你可能想要调查的事情。 - GreenMatt
5个回答

105

你可以使用e.args

[53]: try:
    x2 = myDict['key2']
except KeyError as e:    
    print e.args[0]
   ....:     
key2

根据文档

在异常名称(或元组)后面,except子句可以指定一个变量。该变量绑定到一个异常实例,并且这个实例的参数存储在instance.args中。


3
myDict = {'key1':'value1'}
try:
    x1 = myDict['key1']
    x2 = myDict['key2'] 
except KeyError as e:
    # here i want to use the name of the key that was missing which is 'key2' in this example
    print "missing key in mydict:", e.message

1
这在 Python 2.x 中可能是有效的,但在 Python 3 中不起作用,因为“message”已被弃用并删除:https://www.python.org/dev/peps/pep-0352/#transition-plan - Jérémie

1

对于KeyErrors,sys.exc_info()的第二个元素(索引1)保存了键:

import sys
try:
    x1 = myDict['key1']
    x2 = myDict['key2'] 
except KeyError:
    print 'KeyError, offending key:', sys.exc_info()[1]

输出:

KeyError,错误的键:'key2'


我得到的结果与使用print e相同。 - yossi
1
我回答完这个问题之后,它被编辑了。我目前不熟悉Django,因此不知道在该环境下是否有效,尽管我认为应该有效。 - GreenMatt
@yossi:请看我对于QueryDict问题的评论。 - GreenMatt

-3

简单来说,KeyError 的响应就是键本身,如果你想利用它,只需要按照原样调用错误即可。

myDict = {'key1':'value1'}

try:
    x1 = myDict['key1']
    x2 = myDict['key2'] 
except KeyError as missing_key:
    # Used as missing_key for readability purposes only
    print(f"Trying to access a <dict> with a missing key {missing_key}")

附言:这是在 Python 版本 3.8.12 上测试过的。


1
尽管这样做可以工作,但它是具有误导性的,因为missing_key不是一个字符串对象,而是一个错误对象。它能够工作是因为当一个错误对象被格式化成一个字符串时,它会触发__str__函数。 - theQuestionMan

-15

因为您的字典实际上是一个QueryDict,并且因此返回不同的错误消息,所以您需要解析异常消息以返回单引号中的第一个单词:

import re
#...
except KeyError as e:
    m = re.search("'([^']*)'", e.message)
    key = m.group(1)

2
我认为也许有一种不需要变通方法,但如果找不到我就会使用这个,谢谢! - yossi
3
这样做过于复杂,速度慢,占用内存和CPU效率低,而且未来容易出错。请避免这种方式! - tomasbedrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接