【问题标题】:More pythonic way for exceptions? [closed]更多pythonic方式的异常? [关闭]
【发布时间】:2014-02-05 13:27:52
【问题描述】:

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

我的实现

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()

【问题讨论】:

  • "pythonic" = "走通向目标的明显路径",主要是。
  • @millimoose 两条路径对我来说都很明显 =) 但更明显的是什么?

标签: python django exception


【解决方案1】:

文档告诉我们:

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

可以说这种方式并不“显而易见”,但它既平坦,又减少了冗余,并将相关的东西放在一起。

【讨论】:

  • “查询”或“尝试”?
  • @TravisGriggs “查询”实际上非常好。
【解决方案2】:

我并不真正认为自己是“python Guru”,无论如何,这是我的建议:

  • 为了使您的代码易于维护,我了解到限制代码的输出点是个好主意。
  • 另一个提高可读性的好习惯是按预期使用块:当有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,因此无需指定其分配。

【讨论】:

  • 我非常不同意摆弄局部变量会使这更容易阅读。要找出此函数返回的内容,您必须向后工作以查看分配给res 的内容。使函数具有更少的本地状态而不是具有单个返回更好,这是一种观点。
  • 我故意写了“维护”:我同意这并不容易阅读,但至少你必须遵循你的返回值的所有分配,看看它是如何演变的。显然,所有这些赋值都必须接近函数代码的末尾。可能存在多个returns 的事实并不能简化这项工作,并且可能需要完全相同的研究工作。
  • 我会尝试减少研究工作量,而不是仅仅改变折叠躺椅来改进代码的不相关属性。 (我已经在我的回答中尝试过。)
【解决方案3】:

来自the Zen of Python (import this):

平面比嵌套好。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 2017-05-21
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    相关资源
    最近更新 更多