Skip to main content
 首页 » 编程设计

python try except 作为一个函数来评估表达式

2025年05月04日11dyllove98

我已经尝试创建一个函数来尝试表达式并在出现错误时返回零。

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=[]))