例外情况的更具python风格的方式?

例外情况的更具python风格的方式?,python,django,exception,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.DoesNotExi

我有一个方法,它必须返回三个对象中的一个,这取决于它们的存在

我的实现

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块更具python风格的实现,还是一个更具python风格的实现

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()
从(
导入此
):

平的比嵌套的好


我更喜欢第一个版本。

< P>我不认为自己是“Python Guru”,不管怎么说,这是我的建议:

  • 为了使代码易于维护,我了解到限制代码的输出点是一个好主意
  • 另一个良好的可读性实践是按预期使用块:当有
    if
    块时,避免将
    return
    放在块内:只需使用
    else
    块,我发现这也适用于
    try…除了
    块。当然,这只有在深度不太重要的情况下才有效
因此,我要写下:

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
,因此无需指定其分配。

文档告诉我们:

django.core.exceptions
中定义了
ObjectDoesNotExist
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

可以说,这种方式并不“明显”,但它是扁平的,减少了冗余,并将相关的东西保持在一起。

主要是“pythonic”=“采取明显的途径实现目标”。@millimoose这两条途径对我来说都很明显=),但更明显的是什么呢?我非常不同意摆弄局部变量会使这更容易阅读。要了解此函数返回的内容,必须向后查看分配给
res
的内容。让函数具有更少的局部状态是否比使用单个返回更好,这是一个观点。我特意写了“维护”:我同意这不容易阅读,但至少你必须遵循返回值的所有赋值,以查看它是如何演变的。显然,所有这些赋值都必须接近函数代码的末尾。事实上,可能存在多个
返回
s并不能简化这项工作,而且可能需要完全相同的研究工作。在这项工作中,我将尝试减少研究工作的数量,而不是只是摆弄躺椅来改善代码的一个不相关属性。(我在回答中试过。)“查询”或“尝试”?@TravisGriggs“查询”实际上非常好。