我已经尝试创建一个函数来尝试表达式并在出现错误时返回零。
def try_or_zero(exp):
try:
exp
return exp
except:
return 0
这显然行不通。似乎问题在于 python 没有任何形式的惰性求值,因此表达式在传递给函数之前先求值,因此它在进入函数之前引发错误,因此它永远不会通过 try 逻辑。 有谁知道这是否可以在 Python 中完成? 干杯
请您参考如下方法:
It seems the problem is that python doesn't have any form of lazy evaluation
错误...是的,但可能不是您期望的形式。函数参数在传递给函数之前确实被评估过,所以
try_or_zero(foo.bar())
确实会被执行为:
param = foo.bar()
try_or_zero(param)
现在 python 函数是普通对象(它们可以用作变量,作为参数传递给函数等),并且它们仅在应用调用运算符(parens,有或没有参数)时被调用,因此您可以传递一个函数到 try_or_zero 并让 try_or_zero 调用该函数:
def try_or_zero(func):
try:
return func()
except Exception as e:
return 0
现在你要反对 1/如果函数需要参数,这将不起作用,并且 2/必须为此编写一个函数是 PITA - 这两个反对意见都是有效的。希望 Python 也有一个快捷方式来创建由单个(即使任意复杂)表达式组成的简单匿名函数:lambda。此外,python 函数(包括“lambda 函数”——从技术上讲,它们是普通函数)是闭包——它们捕获定义它们的上下文——因此很容易将所有这些包装在一起:
a = 42
b = "c"
def add(x, y):
return x + y
result = try_or_zero(lambda: add(a, b))
关于异常处理的附注:
首先不要使用 bare except,至少要捕获 Exception(否则您可能会阻止某些异常 - 如 SysExit - 按预期工作)。
此外,最好只捕获您在给定点期望的确切异常。在你的情况下,你可能想传递一个你想忽略的异常元组,即:
def try_or_zero(func, *exceptions):
if not exceptions:
exceptions = (Exception,)
try:
return func()
except exceptions as e:
return 0
a = 42
b = "c"
def add(x, y):
return x + y
result = try_or_zero(lambda: add(a, b), TypeError))
这将防止您的代码掩盖意外错误。
最后:您可能还想添加对异常情况下非零返回值的支持(并非所有表达式都应该返回 int ):
# XXX : python3 only, python2 doesn't accept
# keyword args after *args
def try_or(func, *exceptions, default=0):
if not exceptions:
exceptions = (Exception,)
try:
return func()
except exceptions as e:
return default
# adding lists is legit too,
# so here you may want an empty list as the return value
# instead
a = [1, 2, 3]
# but only to lists
b = ""
result = try_or(lambda: a + b, TypeError, default=[]))
