如何传递带参数的函数作为参数

时间:2017-12-31 15:52:35

标签: python-3.x function

我有很多方法,编写起来非常简单,但都需要处理异常。异常管理总是一样的,所以我想把一个包装器写成一个函数,用一个特定的函数调用实例作为参数调用。有可能吗?

这些方面的东西(这是一个不起作用的例子):

def g(h):
    while True:
        try:
            x = h()
        except:
            # got an error
            print ("Unexpected error. Retry.")
        else:
            # everything is fine
            return x

def f1(x):
    # do something that may fail (e.g. access a distant server)
    y = (...whatever...) 
    return y

def f2(x,y):
    # do something else that may fail (e.g. access a distant server, but different request)
    z = (...whatever...) 
    return z

print (g(f1(3)))
print (g(f1(6)))
print (g(f2(5,'abc')))

注意:我正在寻找一个不需要类定义的答案。另外,我不熟悉python中的lambda函数,但是它可以成为解决方案的一部分吗?

2 个答案:

答案 0 :(得分:1)

您需要从第一个函数返回函数。

def g(h):
    def f(*arguments):
        try:
            x = h(*arguments)
        except:
            # got an error
            print ("Unexpected error. Retry.")
        else:
            # everything is fine
            return x
    return f

我使用*运算符来允许可变数量的参数:here

每次使用函数h调用g时,它将返回一个函数,当使用某些参数调用时,将使用相同的参数调用h(但在错误处理内部)。

您现在可以将其用于:

g(f1)(3)

或者,您可以直接在g方法中使用*运算符,以避免创建新函数。

def g(h, *arguments):
    try:
        x = h(*arguments)
    except:
        # got an error
        print ("Unexpected error. Retry.")
    else:
        # everything is fine
        return x

然后你会这样称呼它:

g(f1, 3, 4)

我找到了第一个替代清洁剂,特别是因为你可以拥有安全的功能,你将会操纵:

safe_f1 = g(f1)
safe_f1(3)

答案 1 :(得分:1)

这可能会有所帮助:

使用装饰器

def exception_handler_wrapper(fn):
    def new_fn(*args, **kwargs):
        try:
            result = fn(*args, **kwargs)
        except Exception as e:
            # return error string or print error string or log error string
            # or do whatever suits you, with the exception
            return "Error occured:" + str(e)
        else:
            return result
    return new_fn


@exception_handler_wrapper
def f1(x):
    # do something that may fail (e.g. access a distant server)
    # emulating something that may fail:
    if x % 2 == 0:
        return "success"
    else:
        raise ValueError("x not even")


@exception_handler_wrapper
def f2(x, y):
    # do something else that may fail (e.g. access a distant server, but
    # different request)
    # emulating something that may fail:
    if x != 0 or y != 'abc':
        return "success"
    else:
        raise Exception("Sum not 100")

print("Expression f1(3):", f1(3))
print("Expression f1(6):", f1(6))
print("Expression f2(5, 'abc'):", f2(5, 'abc'))

,输出结果为:

Expression f1(3): Error happend:x not even
Expression f1(6): success
Expression f2(5, 'abc'): success

现在有了你要处理其异常的任何函数,只需将@exception_handler_wrapper放在def之前,你就可以正常调用该函数,而不是像以下那样调用它:{{ 1}}。