什么是“如果可能,做到这一点”的pythonic方式?
问题描述:
我想知道如何写出最好/最pythonic的情况:如果可以做到,那就做吧。如果不是,就放手吧。什么是“如果可能,做到这一点”的pythonic方式?
例如: 我有一个从数据库加载数据的函数。如果给出可写的目标,则将数据写入文件。独立于正在写入或未写入的文件,数据总是被返回。我可以当然检查是否有可写的位置,如果是这样的话,将数据写入文件。但它似乎是一种非pythonic的方式,我认为“最好是要求宽恕而不是许可”。
我实现这个像这样:
def loadData(dest=False):
data = someDBRequest()
try:
with open(dest, 'w') as fh:
json.dump(data, fh)
except:
pass
return data
,因为我实现了一个无用的,除了这种莫名其妙的感觉不好,毕竟我预计DEST不总是被设置为一个位置,因为该函数可以不设置它被称为。我也觉得这不是一个应该以某种方式记录或处理的错误。
这是一个正确的方法,或者你会建议更好/更pythonic?
答
在这个特定的情况下,我会默认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
区块内,尽可能少地捕捉异常。
答
与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
另一个原则是“显式优于隐式”。我也不认为你在这里写的代码是非常可读的,你不喜欢它自己。只要做一些最适合你的事。 如果dest提供但不可写,你真的不想提醒吗? – philippd