例外的更多pythonic方式?

时间:2014-01-16 14:56:39

标签: python django exception

我有一个方法必须根据它们的存在返回三个对象中的一个。

我的实施

try:
    return Model.objects.get(param=param)
except Model.DoesNotExist as ex:
    # go to the next verification
    pass

try:
    return RelatedModel.objects.get(param=param).model
except RelatedMolel.DoesNotExist as ex:
    # get the default model
    pass

return Model.objects.get_default()

对python的大师提出这样的问题 - 它是一个比内部try / catch块更加pythonic的实现还是?

try:
    return Model.objects.get(param=param)
except Model.DoesNotExist as ex:

    try:
        return RelatedModel.objects.get(param=param).model
    except RelatedModel.DoesNotExist as ex:

        return Model.objects.get_default()

3 个答案:

答案 0 :(得分:6)

来自the Zen of Pythonimport this):

  

Flat比嵌套好。

在这种情况下我更喜欢第一个版本。

答案 1 :(得分:2)

文档告诉我们:

  

ObjectDoesNotExistdjango.core.exceptions中定义。 DoesNotExist是基础ObjectDoesNotExist异常的子类,它在每个模型类上提供,作为识别无法找到的特定对象类型的方法。

所以我要做的是:

queries = [lambda: Model.objects.get(param=param),
             lambda: RelatedModel.objects.get(param=param).model,
             lambda: Model.objects.get_default()]

for query in queries:
    try:
        return query()
    except ObjectDoesNotExist:
        pass

可以说这种方式不是“显而易见”,但它既平坦,又减少冗余,并将相关事物保持在一起。

答案 2 :(得分:0)

我并不认为自己是“蟒蛇大师”,无论如何,这是我的建议:

  • 为了使您的代码易于维护,我了解到限制代码的输出点是个好主意。
  • 可读性的另一个好方法是按预期使用块:当存在if块时,避免诱惑将return置于其中:只使用else块,我发现这也适用于try...except块。当然,只有深度不太重要时才有效。

因此,我会这样写:

try:
    res = Model.objects.get(param=param)
except Model.DoesNotExist:
    try:
        res = RelatedModel.objects.get(param.param).model
    except RelatedModel.DoesNotExist:
        res = Model.objects.get_default()
return res

由于您未使用ex,因此无需指定其分配。