python try除了作为评估表达式的函数

时间:2019-01-18 10:32:38

标签: python python-3.x try-except

我尝试创建一个尝试表达式的函数,如果出现错误,则返回零。

def try_or_zero(exp):
    try:
        exp
        return exp
    except:
        return 0

显然不起作用。似乎问题在于python没有任何形式的惰性求值,因此在将表达式传递给函数之前先对其求值,因此表达式在进入函数之前会引发错误,因此它永远不会通过try逻辑。 有人知道这是否可以用Python完成吗? 干杯

4 个答案:

答案 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