Python ValueError 异常没有被正确捕获

Posted

技术标签:

【中文标题】Python ValueError 异常没有被正确捕获【英文标题】:Python ValueError Exception not being caught properly 【发布时间】:2018-04-04 00:43:58 【问题描述】:

item是一个python字典

print item.get('body')

在某些情况下会给出以下输出:

“1211V1”

然而,item.get('body') 大多具有以下格式的 unicode 字符串:

u'"points_token_id":"327727a0-3909-4132-8fa2-ee45146add1e"'

我需要将上面的 unicode 字符串转换为 python 字典。所以我这样做:

try:
    body_dic = json.loads(item.get('body'))
    body_string = ""

    for body_item in body_dic.keys():
        body_string += body_item + ": 'required': True, 'type': 'resource', 'value': " + str(body_dic.get('body_item')) + "\n\t\t\t\t"

except Exception as e:
    print "futt gayaa"
    print type(e).__name__
    print e.args
    body_string = item.get('body')

然后是一堆代码。所以在上面的时刻 item.get('body') 出来是 "1211V1" 应该引发 ValueError Exception 并且执行流程应该进入 except 块。我说的对吗?

但是它没有被提升,执行流程继续进入下一行:

for body_item in body_dic.keys():

然后引发以下异常:

属性错误 ("'unicode' 对象没有属性 'keys'",)

如果我更改上面的 except 块以捕获通用异常,我会知道:

except Exception as e:
    print "futt gayaa"
    print type(e).__name__
    print e.args
    body_string = item.get('body')

请帮助我理解这一点。在我看来,当第一个异常被引发时(在我们的例子中应该是 ValueError Exception),控制流应该进入 catch 块。为什么它会转到下一行代码,然后当 Attribute Exception 被引发时它会被捕获。

【问题讨论】:

请提供一个minimal reproducible example 来证明错误。 你可能序列化了一个字符串,而不是一个字典。所以json.loads 返回一个字符串 【参考方案1】:

所以你的问题是你有一个字典序列,其属性主体是一个 JSON 字符串。它可能是:

"1211V1"

或:


    "points_token_id":"327727a0-3909-4132-8fa2-ee45146add1e"

这是一个 JSON 字符串或 JSON 对象。通过json.loads()ing 这个字符串,你总是得到一个有效的 Python 值,分别是 Python str 或 Python dict。你想要做的是检测它是否是一个或另一个:

json_body = json.loads(item['body'])
if type(json_body) is dict:
    for key, value in json_body.items():
        json_body[key] = 'required': True, 'type': 'resource', 'value': value
    body_string = json.dumps(json_body)
else:
    pass # Handle the "1211V1"

【讨论】:

【参考方案2】:

假设,正如你所写的

print item.get("body")

按字面意思返回

"1211V1"

那么引号就是字符串本身的一部分。

所以你有效地调用

json.loads('"1211V1"')

您正在加载 JSON 字符串文字的位置——完全有效。然后,当然,你会得到一个 AttributeError 来尝试在 unicode 对象上调用 .keys()

如果您使用print 调试问题,它可能会以这种方式误导您——如果您真的想确定遇到问题的对象是什么,您最好经常这样做,写print(repr(obj))。在这种情况下,这会告诉你 item.get("body")u'"1211V1"'

【讨论】:

我也有点不安,您似乎正在尝试使用字符串连接手动构建某种 JSON 字符串。我不会问为什么,但我敢打赌你会在没有充分理由的情况下走错路…… 感谢@Iguananaut。完全有道理。至于方法,至于我为什么要尝试手动构建某种 JSON 字符串,长话短说,有一个遗留工具需要某种格式的数据。我们需要扩展代码。 (请不要问为什么现在重构不是一个选项:D)因此,所有这些马戏团都围绕着字符串和 JSON。 @qre0ct 您仍然可以使用json 模块构建它,而不是添加strs、json.dumps()

以上是关于Python ValueError 异常没有被正确捕获的主要内容,如果未能解决你的问题,请参考以下文章

Python异常 ValueError的问题详解

为啥没有显示 ValueError 异常?

Python ValueError 继承了自定义异常行为

使用 Python 训练 arima 模型时如何解决 LinAlgError 和 ValueError

Python CodeLab 关于异常的问题——尝试,除了 ValueError

理解 ValueError:python 中的“无效数字”