提问人:Kalev Maricq 提问时间:7/3/2019 更新时间:7/3/2019 访问量:11589
Python 定义 IFERROR 函数
Python Define IFERROR function
问:
我正在尝试像在 Excel 中一样在 python 中定义我自己的 IFERROR 函数。(是的,我知道我可以写 try/except。我只是想为我经常使用的 try/except 模式创建一个内联速记。当前的用例正在尝试获取某些远程表的多个属性。用于连接到它们的模块会给出各种错误,如果发生这种情况,我只想记录在尝试获取该属性时遇到错误。
我尝试过: 搜索发现了许多线程,其中最有用的是:
阅读这些线程后,我尝试编写以下内容:
>>> def iferror(success, failure, *exceptions):
... try:
... return success
... except exceptions or Exception:
... return failure
...
>>> iferror(1/0,0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
我还尝试使用上下文管理器(对我来说是新的):
>>> from contextlib import contextmanager as cm
>>> @cm
... def iferror(failure, *exceptions):
... try:
... yield
... except exceptions or Exception:
... return failure
...
>>> with iferror(0,ZeroDivisionError) as x:
... x=1/0
...
>>> print(x)
None
有没有办法定义一个函数来执行预定义的 try/except 模式,如 IFERROR?
答:
好吧,我找到了一种方法,但我不太确定,这是否是你要找的。
首先,如果调用函数,则会发生错误,因此函数根本无法启动!因此,我给函数的第一个参数一个字符串。
因此,该函数获取您的“测试”并使用 “控制” 它。这是我的代码:eval()
def iferror(success: str, failure, *exceptions):
try:
# Test
return eval(success)
except exceptions or Exception:
return failure
iferror("1/0", "Hi there!")
我希望我能希望你。
评论
问题在于,在输入函数之前,函数参数会被计算(大多数编程语言都是这种情况,一个很大的例外是Haskell)。不管是什么,先运行并抛出错误。iferror(1/0,0)
iferror
1/0
我们必须以某种方式延迟计算,以便它发生在函数内部,在块的上下文中。一种方法是使用一个字符串 (),然后可以求值
。但应该尽可能避免,并且有一个更轻量级的替代方案:函数体在函数被调用之前不会被计算,因此我们可以将表达式包装在一个函数中并传递它:1/0
try
iferror('1/0', 1)
iferror
eval
def iferror(success, failure, *exceptions):
try:
return success()
except exceptions or Exception:
return failure
def my_expr():
return 1/0
print(iferror(my_expr, 42))
42
这里的关键部分是我们不直接打电话。我们将其作为函数传递给 ,然后调用 ,最终执行 。my_expr
iferror
success()
return 1/0
唯一的问题是,我们必须将函数参数 () 从正常的代码流中提取出来,并放入一个单独的函数定义中,我们必须给它一个名称(即使认为它只使用一次)。1/0
这些缺点可以通过使用 来避免,它允许我们内联定义单表达式函数:lambda
def iferror(success, failure, *exceptions):
try:
return success()
# ^^
except exceptions or Exception:
return failure
print(iferror(lambda: 1/0, 42))
# ^^^^^^^
42
[现场演示]
与最初的尝试相比,只需要进行两项更改:将表达式包装在 中,这会延迟计算,并使用 in 调用 lambda,这会触发函数体的计算。lambda:
()
try: return success()
评论
return success()
和?iferror(lambda: 1/0, 0)