gpt4 book ai didi

Python 定义 IFERROR 函数

转载 作者:太空宇宙 更新时间:2023-11-03 23:57:56 26 4
gpt4 key购买 nike

我正在尝试像在 Excel 中一样在 Python 中定义我自己的 IFERROR 函数。 (是的,我知道我可以写 try/except。我只是想为我经常使用的 try/except 模式创建一个内联速记。)当前的用例是试图获取一些远程表的几个属性。用于连接它们的模块会出现各种错误,如果发生这种情况,我只想记录在尝试获取该属性时遇到了错误。

我尝试过的:搜索显示了一些线程,其中最有用的是:

Frequently repeated try/except in Python

Python: try-except as an Expression?

阅读这些主题后,我尝试编写以下内容:

>>> 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?

最佳答案

iferror(1/0,0) 的问题是函数参数在函数被输入之前被计算(大多数编程语言都是这种情况,Haskell 是一个很大的异常(exception))。无论 iferror 做什么,1/0 都会先运行并抛出错误。

我们必须以某种方式延迟 1/0 的评估,以便它发生在函数内部,在 try block 的上下文中。一种方法是使用字符串 (iferror('1/0', 1)),然后 iferror 可以 eval .但是应该尽可能避免使用 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

[ Live demo ]

与您最初的尝试相比,只需要进行两处更改:将表达式包装在 lambda: 中,这会延迟求值,并在 try 中使用 () : 返回 success() 以调用 lambda,这将触发对函数体的评估。

关于Python 定义 IFERROR 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56858036/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com