简体   繁体   中英

Weird behavior of a custom exception in Python

There are many questions about custom exception in Python, but I couldn't find my case.

In Python 3.7 I'm defining a class Asterism that has a name and a 2-axes array of 2D points. The constructor must be able to validate the input, which means that it has to raise an exception if the passed array does not have 2 axes or if it is not made by 2D elements. I consider this as a code-breaking error, so if this exception is raised the execution must be terminated. This is the code for the classes:

import sys
import numpy as np

class WrongAsterism(Exception):
    def __init__(self, value):
        self.message = value
    def __str__(self):
        return str(self.message)

class Asterism:
    def __init__(self, name, points_array):
        self.name = name
        if(len(points_array.shape)!=2):
            raise WrongAsterism("The asterism must be a 2-axes numpy array. Quitting.")
        elif(points_array.shape[1]!=2):
            raise WrongAsterism("The asterism must consist of 2D points. Quitting.")
        else:
            self.points = points_array

I wanted to test the code, so I added the following lines:

try:
    np.random.seed(6)
    a = Asterism("Ursa Major", np.random.rand(9,2)*10-5)
except WrongAsterism:
    print("Error!")
    sys.exit()

print("The asterism name is {}.".format(a.name))
print("It has {} 2D points.".format(a.points.shape[0]))
print("Its points are:\n{}".format(a.points))

This case has a correct input, so I get:

The asterism name is Ursa Major.
It has 9 2D points.
Its points are:
[[ 3.92860151 -1.68020195]
 [ 3.21229123 -4.58303374]
 [-3.9234332   0.95052064]
 [ 0.29817362 -0.81192571]
 [-1.64592151  1.22519432]
 [-0.61858574  2.35882106]
 [ 0.18036412  0.788586  ]
 [ 1.45355096  4.90224271]
 [ 3.19858197 -0.86799065]]

However, if I try to define the object with a wrong input, for example with the line a = Asterism("Ursa Major", np.random.rand(9,3)*10-5) , in which the array has 2 axes but the points are 3D, or with a = Asterism("Ursa Major", np.random.rand(9,2,3)*10-5) , where the array has 3 axes, in both cases I get

Error!
An exception has occurred, use %tb to see the full traceback.

SystemExit

instead of the expected error message.

Following the indications found in similar questions, I tried to redefine the class WrongAsterism also in two alternative ways, namely

class WrongAsterism(Exception):
    pass

and

class WrongAsterism(Exception):
    def __init__(self, msg='My default message', *args, **kwargs):
        super().__init__(msg, *args, **kwargs)

but nothing changes.

So, first question is "How can I get the desired custom error message?"

However, I have another problem that puzzles me badly. Among the others, I also tried to comment out the sys.exit() , and in this case I always get

Error!
The asterism name is Ursa Major.
It has 9 2D points.
Its points are:
[[ 3.92860151 -1.68020195]
 [ 3.21229123 -4.58303374]
 [-3.9234332   0.95052064]
 [ 0.29817362 -0.81192571]
 [-1.64592151  1.22519432]
 [-0.61858574  2.35882106]
 [ 0.18036412  0.788586  ]
 [ 1.45355096  4.90224271]
 [ 3.19858197 -0.86799065]]

even when I initialize the object with a wrong input! To be more precise, the code prints "Error!" only when I use the wrong input, but then it always prints the (previously used) good input.

Clearly, I'm missing some very basic issue here, but I can't figure out what it is.

Instead of

except WrongAsterism:
    print("Error!")
    sys.exit()

You need to have

except WrongAsterism as err:
    print(err)
    sys.exit()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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