Handing multiple exception of same type and resume execution in python

久未见 提交于 2020-01-02 06:35:54

问题


It appears that one cannot resume the execution of test once you hit the raise the user defined exception in Python. But in my scenario I want to check error occurred for different input values. But Current implementation is restricting to continue the check error for the different input vectors.

However, before coming up with some sort of convoluted solution to my problem, I figured I would ask the experts and see if there is something I'm missing. Unfortunately, I cannot change this paradigm easily without significant re-factoring.

My application looks similar to this:

  • Input will be given as numGen function. This numGen function add the input to the random number. In my example I am checking for 10 different random number.
  • Note Input is also will be varying as well as the range of random number generation

Problem statement:

  • I want to check for each input whether error is occurred and if any error occurred raise exception and store the information of which input

  • Continue the program execution for other input as well, But In my implementation it I'm not able to continue further execution.

Questions:

  • How to raise the exceptions later, without using unittest module?

from random import randint

class RND_ERROR(Exception):
    def __init__(self, ErrNum, *arg, **kwargs):
        self.RND_ERR_NR = int(ErrNum)
        self.RND_ERR_MSG = ""         
        if self.RND_ERR_NR == 0x00000000:
            self.RND_ERR_MSG = "NO ERROR"
        elif self.RND_ERR_NR == 0x00000001:
            self.RND_ERR_MSG = "RANDOM NUMBER IS ONE"
        elif self.RND_ERR_NR == 0x00000002:
            self.RND_ERR_MSG = "RANDOM NUMBER IS TWO"
        elif self.RND_ERR_NR == 0x00000003:
            self.RND_ERR_MSG = "RANDOM NUMBER IS THREE"
        else:
            self.RND_ERR_MSG = "RANDOM NUMBER GREATER THAN THREE"
    def __str__(self):
        return "RND ERROR (0x%08X): %s" % (self.RND_ERR_NR,self.RND_ERR_MSG)

    def __repr__(self):
       return self.__str__()

def check_error(b):
    print "dict",b
    count = 0

    for i, error_nr in b.items():

        error_nr = error_nr % 2
        print "key:val",i, error_nr
        if error_nr ==0:
            count = count +1
            # print count
        elif error_nr > 0:

            # print error_nr
            raise RND_ERROR(error_nr)

def numGen(input):
    from random import randint
    result= {}
    for i in range(9):
        j = (randint(0,4))
        result[i] = input+j
        result.update()
    check_error(result)

if __name__ == '__main__':
    try:
        numGen(3)
    except BaseException as e:
        print e

Output1: # Since at the 6th input error occurred and execution stopped **(Some what Best case)**  
dict {0: 6, 1: 6, 2: 6, 3: 6, 4: 4, 5: 6, 6: 3, 7: 3, 8: 7}
key:val 0 0
key:val 1 0
key:val 2 0
key:val 3 0
key:val 4 0
key:val 5 0
key:val 6 1
RND ERROR (0x00000001): RANDOM NUMBER IS ONE

**Output2:**
dict {0: 7, 1: 6, 2: 4, 3: 3, 4: 6, 5: 6, 6: 7, 7: 5, 8: 4}
key:val 0 1

RND ERROR (0x00000001): RANDOM NUMBER IS ONE

Expected Output:

Input1 - Pass
Input2 - Pass
Input3 - Pass
Input4 - Pass
Input5 - Pass
Input6 - RANDOM IS TWO (exception occurred)
Input7 - Pass  # execution continued for next input check
Input8 - Pass
Input9 - RANDOM IS ONE (exception occurred)
Input10 - Pass  # execution continued for next input check

I found link, which looks similar to my requirement. Difference is instead of checking error in file reading and stack up the error if found. In my case it is checking for inputs.

Similar requirement

Thanks in advance!!


回答1:


What you've defined is a logical contradiction: you want to raise an exception and continue normal execution. The common meaning of raise exception in a 4th-generation language means that you do not want to continue normal execution. Make up your mind.

You are welcome to print a message, not raise an exception, and continue normal operation. If you want to raise the exception later, you are welcome to do that.

If you want to check for an error on each input, then you cannot make the error check itself an exception condition. I'm guessing a little here: you want to report every discrepancy, but then not raise an exception until you've gone through all the input cases. Try this: it splits the error handling into a non-exception routine. I've left a lot of your exception-handling stuff intact, in case you want to fill it in with other code.

class RND_ERROR(Exception):
    def __init__(self, ErrNum, *arg, **kwargs):
        self.RND_ERR_NR = int(ErrNum)
        self.RND_ERR_MSG = ""

    def __str__(self):
        return "RND ERROR (0x%08X): %s" % (self.RND_ERR_NR,self.RND_ERR_MSG)

    def __repr__(self):
        return self.__str__()


def handle_error(ErrNum):
    RND_ERR_NR = int(ErrNum)
    RND_ERR_MSG = ""
    if RND_ERR_NR == 0x00000000:
        RND_ERR_MSG = "NO ERROR"
    elif RND_ERR_NR == 0x00000001:
        RND_ERR_MSG = "RANDOM NUMBER IS ONE"
    elif RND_ERR_NR == 0x00000002:
        RND_ERR_MSG = "RANDOM NUMBER IS TWO"
    elif RND_ERR_NR == 0x00000003:
        RND_ERR_MSG = "RANDOM NUMBER IS THREE"
    else:
        RND_ERR_MSG = "RANDOM NUMBER GREATER THAN THREE"

    print "RND ERROR (0x%08X): %s" % (RND_ERR_NR, RND_ERR_MSG)

def check_error(b):
    print "dict",b
    count = 0
    need_exception = False

    for i, error_nr in b.items():

        error_nr = error_nr % 2
        print "key:val",i, error_nr
        if error_nr ==0:
            count = count +1
            # print count
        elif error_nr > 0:
            # print error_nr
            handle_error(error_nr)
            need_exception = True

    if need_exception:
        raise RND_ERROR(49374)


def numGen(input):
    from random import randint
    result= {}
    for i in range(9):
        j = (randint(0, 4))
        result[i] = input+j
        result.update()
        # print "iteration", i, j
    check_error(result)

try:
    numGen(3)
except BaseException as e:
    print e
finally:
    print "Finished"

output:

dict {0: 6, 1: 4, 2: 6, 3: 5, 4: 4, 5: 4, 6: 5, 7: 6, 8: 3}
key:val 0 0
key:val 1 0
key:val 2 0
key:val 3 1
RND ERROR (0x00000001): RANDOM NUMBER IS ONE
key:val 4 0
key:val 5 0
key:val 6 1
RND ERROR (0x00000001): RANDOM NUMBER IS ONE
key:val 7 0
key:val 8 1
RND ERROR (0x00000001): RANDOM NUMBER IS ONE
RND ERROR (0x0000C0DE): 
Finished



回答2:


You can catch the errors as they occur and process them later:

def numGen(input):
    from random import randint
    result= {}
    errors = []
    for i in range(9):
        j = (randint(0,4))
        result[i] = input+j
        result.update()    # This line does nothing...
        try:
            check_error(result)
        except RND_ERROR as e:
            errors.append((i, e))

    for i, error in errors:
        print(i, error)


来源:https://stackoverflow.com/questions/35089487/handing-multiple-exception-of-same-type-and-resume-execution-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!