确定Python函数中返回值的数目

2024-04-26 11:38:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个decorator,它捕捉目标函数中引发的错误,并允许用户继续执行脚本(绕过函数)或退出脚本。在

def catch_error(func):
    """
    This decorator is used to make sure that if a decorated function breaks 
    in the execution of a script, the script doesn't automatically crash. 
    Instead, it gives you the choice to continue or gracefully exit.    

    """
    def caught(*args):
        try:
            return func(*args)
        except Exception as err:
            question = '\n{0} failed. Continue? (yes/no): '.format(func.func_name)
            answer = raw_input(question)
            if answer.lower() in ['yes','y']:
                pass
            else:
                print "   Aborting! Error that caused failure:\n"
                raise err 
            return None
    return caught

请注意,如果用户选择绕过错误返回函数并继续执行脚本,则decorator将返回None。这对于只返回单个值的函数很有效,但对于尝试解压多个值的函数来说,这会崩溃。例如

^{pr2}$

有没有一种方法可以确定目标函数应该返回的值的数量?例如,类似于:

^{3}$

像往常一样,如果有更好的方法来做这种事,请告诉我。谢谢!在

更新:

谢谢你的建议。我决定将catch_error的范围缩小到一个函数类,它只返回一个字符串值。我只是将返回多个值的所有函数拆分为返回单个值的单独函数,以使它们兼容。我一直希望使catch_错误更通用(关于如何实现这一点,有一些有用的建议),但是对于我的应用程序来说,这有点过分了。再次感谢。在


Tags: theto函数用户脚本目标returnthat
3条回答

您的decorator无法预测您的函数将返回什么,但是没有什么可以阻止您告诉装饰器要模拟什么返回签名:

@catch_error([None, None])
def tuple_returner(n):
    raise Exception
    return [2, 3]

不是返回None,而是返回其参数([None, None])。在

编写一个接受decorator的参数有点棘手:表达式catch_error([None, None])将被计算,并且必须返回将应用于修饰函数的实际decorator。看起来像这样:

^{pr2}$

请注意,即使您只希望它返回None,也需要执行一次:

^{3}$

Martijn Pieters的回答是正确的,这是the Halting Problem的一个具体情况

但是,您可以通过向decorator传递一个错误返回值来绕过它。像这样:

def catch_error(err_val):
    def wrapper(func):
        def caught(*args):
            try:
                return func(*args)
            except Exception as err:
                question = '\n{0} failed. Continue? (yes/no): '.format(func.func_name)
                answer = raw_input(question)
                if answer.lower() in ['yes','y']:
                    pass
                else:
                    print "   Aborting! Error that caused failure:\n"
                    raise err 
                return err_val
        return caught
    return wrapper

然后可以使用以下方式进行装饰:

^{pr2}$

另外,作为一个风格点,如果您在包装的函数中获取*args,那么您可能还应该获取{},这样就可以正确地包装接受关键字参数的函数。否则,如果调用wrapped_function(something=value),则包装的函数将失败

最后,作为风格的另一点,看到代码与else一起使用if a: pass是令人困惑的。在这些情况下,请尝试使用if !a。所以最后的代码是:

^{3}$

不,你无法确定。在

Python是一种动态语言,根据输入和其他因素,给定函数可以返回任意大小的序列,或者根本不返回序列。在

例如:

import random

def foo():
    if random.random() < 0.5:
        return ('spam', 'eggs')
    return None

这个函数将返回元组的一半时间,但是None另一半时间,因此Python无法告诉您foo()将返回什么。在

顺便说一句,decorator失败的方式有很多种,而不仅仅是当函数返回调用者随后解包的序列时。如果调用者希望得到一个字典并开始尝试访问键或列表并想知道长度,该怎么办?在

相关问题 更多 >