我尝试创建一个尝试表达式的函数,如果出现错误,则返回零。
def try_or_zero(exp):
try:
exp
return exp
except:
return 0
显然不起作用。似乎问题在于python没有任何形式的惰性求值,因此在将表达式传递给函数之前先对其求值,因此表达式在进入函数之前会引发错误,因此它永远不会通过try逻辑。 有人知道这是否可以用Python完成吗? 干杯
答案 0 :(得分:2)
问题似乎在于python没有任何形式的惰性评估
Err ...是的,但是可能不是您期望的形式。函数参数确实在传递给函数之前已经过评估,因此
try_or_zero(foo.bar())
的确将执行为:
param = foo.bar()
try_or_zero(param)
现在python函数是普通对象(它们可以用作变量,作为参数传递给函数等),并且它们仅在应用调用运算符(有或没有参数的paren)时被调用,因此您可以传递函数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))
关于异常处理的旁注:
首先不要使用裸露的东西,至少要抓住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 0
# 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=[]))
答案 1 :(得分:0)
无需麻烦exec
和其他东西,请使用python函数是对象,因此可以将其作为参数传递的事实
def try_or_zero(exp):
try:
return exp()
except:
return 0
只需调用try_or_zero(my_awesome_func)
(方法中无需())
答案 2 :(得分:-2)
将参数传递给str中的函数,并在函数中执行exec
def try_or_zero(exp):
try:
exec(exp)
return exp
except:
return 0
所以您对函数的调用将如下所示 try_or_zero('1 == 2')
答案 3 :(得分:-2)
您可以通过将表达式包含在函数中来实现此目的。 例如:
th
此外,您的try函数应如下所示:
def ErrorTest():
# the expression you want to try
raise Exception
并将其放在函数中
def try_catch(exp):
try :
exp() # note the paranthesis
except:
return 0
您也可以使用eval()函数来完成此操作,但是您必须将代码放入String中。
try_or_zero(ErrorTest)
OutPut: 0