简体   繁体   English

当函数用作参数时,try-block不起作用

[英]try-block not working when function is used as argument

I have a function which I pass to another function: 我有一个传递给另一个函数的函数:

def func1(a, b):
    return a/b

The second function is meant to handle exceptions similar to the one raised by func1 : 第二个函数旨在处理类似于func1引发的异常:

def func2(func):
    try:
        return func
    except ZeroDivisionError as e:
        print("0")

If I pass 如果我通过

func2(func1(1,2))

The output is 0.5 , as expected. 如预期的那样,输出为0.5 However, func2(func1(1,0)) raises a ZeroDivisionError that is not caught by the except statement: 但是, func2(func1(1,0))会引发ZeroDivisionError ,该ZeroDivisionError不会被except语句捕获:

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input> in <module>
----> 1 func2(func1(1,0))

<ipython-input> in func1(a, b)
      1 def func1(a, b):
----> 2     return a/b

ZeroDivisionError: division by zero

Can anyone clarify why the except block is not entered in this example? 任何人都可以澄清为什么在此示例中未输入except块吗?

def func3(a,b):
    try:
        a/b
    except ZeroDivisionError as e:
        print("0")

with input func3(1,0) returns 0 , as expected. 输入func3(1,0)结果为0 ,符合预期。

Background : I have a code with multiple API calls, which sometimes return a Connection error. 背景 :我有一个带有多个API调用的代码,有时会返回一个Connection错误。 I want to put all these calls inside a function which attempts a retry after a few seconds. 我想将所有这些调用放在一个函数中,该函数会在几秒钟后尝试重试。

If you must put the check in func2 you will need to make sure that the computation is happening inside func2 . 如果必须将检查放入func2 ,则需要确保计算在func2内部进行。 In your case, the call is func2(func1(1,0)) . 在您的情况下,调用为func2(func1(1,0)) So what is happening under the hood is, when func2 calls func1(1,0) , it is not computing the func1 inside it, instead it is taking the value of func(1,0) , ie it is asking func1 to do its calculation in its own scope, and return only the value. 因此,在func2发生的事情是,当func2调用func1(1,0) ,它没有计算其中的func1 ,而是取了func(1,0)的值,即它正在要求func1进行操作在自己的范围内进行计算,并且仅返回值。 func1 encounters a ZeroDivisionError without entering the Try block of func2 . func1遇到ZeroDivisionError而不进入func2Try块。 Your actual function call becomes func2(return_val_of_func1(1,0)) . 您的实际函数调用变为func2(return_val_of_func1(1,0)) So you are essentially checking whether the value of func1 throws any ZeroDivisionError , which is not possible. 因此,您实际上是在检查func1的值是否引发任何ZeroDivisionError ,这是不可能的。 So instead, what you can do is: 因此,您可以做的是:

def func1(a, b):
    return a/b

def func2(func1,a,b):
    try:
        return func1(a,b)
    except ZeroDivisionError as e:
        print("0")

func2(func1,1,0)

You have written func2 wrong and are calling it wrong. 您写的func2错误,并称之为错误。

Try this instead: 尝试以下方法:

def func2(func):
    try:
        return func()
    except ZeroDivisionError as e:
        print("0")

and call it like this: 并这样称呼它:

func2(lambda:func1(1,2))

Update: 更新:

Also note that func2 will return the return value of func() if there is no ZeroDivisionError exception, but when there is an exception it returns None . 还要注意,如果没有ZeroDivisionError异常, func2将返回func()的返回值,但是当有异常时,它将返回None

func2 will never return ZeroDivisionError as this error was never raised in the try block. func2将永远不会返回ZeroDivisionError,因为在try块中从未引发此错误。 In the try block, you are just returning the output of func1 which will never throw an error. 在try块中,您只是返回func1的输出,它将永远不会引发错误。

You can try: 你可以试试:

def func1(a, b):
    try:
        return a/b
    except ZeroDivisionError as e:
        print("0")


def func2(func):
    return func

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM