【问题标题】:What is the pythonic way of "if possible, do it"?“如果可能,做它”的pythonic方式是什么?
【发布时间】:2017-09-06 09:44:37
【问题描述】:

我想知道如何最好/最 Pythonic 来编写这种情况:如果可以做到,那就去做。如果没有:就离开吧。

示例: 我有一个从数据库加载数据的函数。如果给定了可写目的地,则将数据写入文件。不管文件是否被写入,数据总是被返回。我当然可以检查是否有可写位置,如果有,将数据写入文件。然而,这似乎是一种非 Pythonic 方式,我认为“请求宽恕比请求许可更好”。

我是这样实现的:

def loadData(dest=False):
    data = someDBRequest()
    try:
        with open(dest, 'w') as fh:
            json.dump(data, fh)
    except:
        pass
    return data

这在某种程度上感觉很糟糕,因为我实现了一个无用的 except,毕竟我希望 dest 并不总是被设置到一个位置,因为可以在不设置它的情况下调用该函数。我也觉得这不是应该记录或以某种方式处理的错误。

这是一种正确的方式还是你会建议更好/更蟒蛇?

【问题讨论】:

  • 另一个原则是“显式优于隐式”。我也不觉得你这里写的代码可读性很强,你自己也不喜欢。只做最适合你的事情。如果提供了 dest 但不可写,您真的不想发出警报吗?

标签: python python-2.7 python-2.x


【解决方案1】:

在这种特殊情况下,我会将dest 默认为None,并明确检查None

如果您还想在dest 给出但无效时安静地失败,您可以使用您的方法。但是,我主张用except IOError 替换包罗万象的except 子句。否则,您可能会捕捉到 SyntaxError 等内容。

def loadData(dest=None):
    data = someDBRequest()
    if dest:
       try:
           with open(dest, 'w') as fh:
               json.dump(data, fh)
       except IOError:
           pass
    return data

一般来说,如果你确实依赖“请求宽恕而不是许可”的成语,我认为最好在 try 块中放置尽可能少的代码,并尽可能少地捕获异常.

【讨论】:

    【解决方案2】:

    从 Python 3.4 开始,有一个新工具 contextlib.suppress 允许在没有 except Exception: pass 行的情况下编写类似的代码。

    引用自docs的小例子:

    from contextlib import suppress
    
    with suppress(FileNotFoundError):
        os.remove('somefile.tmp')
    

    从技术上讲,它是一个上下文管理器,它是可重入的(解释为here)并且可重用。这意味着您不必每次都创建一个新的,例如:

    os_errors_ignored = contextlib.suppress(OSError)
    
    with os_errors_ignored:
        # do something
    
    with os_errors_ignored:
        # do something else
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多