4

I've learned recently how to create custom exceptions in Python and implement them into a class. I'm trying to add an additional argument into my exception for more clarity, and can't seem to get the formatting done correctly.

Here's what I'm attempting:

class NonIntError(Exception):
    pass

class intlist(List):

    def __init__(self, lst = []):

        for item in lst:
            #throws error if list contains something other that int
            if type(item) != int:
                raise NonIntError(item, 'not an int') 

            else:
                self.append(item)

Expected Results

il = intlist([1,2,3,'apple'])

>>> NonIntError: apple not an int

Results with error

il = intlist([1,2,3,'apple'])

>>> NonIntError: ('apple', 'not an int')

Restating my question, I would like know how to make my exception appear like the expected results.

23k
  • 1,596
  • 3
  • 23
  • 52

2 Answers2

3

You are initializing your custom exception with two arguments, item and the string 'not an int'. When you initialize the Exception with multiple arguments, the *args will be displayed as a tuple:

>>> raise NonIntError('hi', 1, [1,2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.NonIntError: ('hi', 1, [1, 2, 3])

To get your desired result, pass exactly one string, i.e.:

>>> item = 'apple'
>>> raise NonIntError(item + ' not an int')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.NonIntError: apple not an int
timgeb
  • 76,762
  • 20
  • 123
  • 145
2

According to your class and timgeb's answer, I have a better answer:

When you check the list whether or not its element is int, I recommend you:

class intlist(object):

    def __init__(self, lst = []):
        not_int_list = filter(lambda x: not isinstance(x, int), lst)
        if not_int_list:
            if len(not_int_list) > 1:
                items = ', '.join(not_int_list)
                raise NonIntError(items + ' are not int type')
            item = not_int_list.pop()
            raise NonIntError(item + ' is not int type')

When il = intlist([1,2,3,'apple']), it will return:

>>> NonIntError: apple is not int type

When il = intlist([1,2,3,'apple','banana']), it will return:

>>> NonIntError: apple, banana are not int type

It has strengthen readable when the list includes single or multiple non-int element will return appropriate error message.


Explanation:

not_int_list = filter(lambda x: not isinstance(x, int), lst)

Using filter and isinstance will assist you on coding readable class object and checking mechanism.

if len(not_int_list) > 1:
    items = ', '.join(not_int_list)
    raise NonIntError(items + ' are not int type')
item = not_int_list.pop()
raise NonIntError(item + ' is not int type')

It will return appropriate error message when the list has single or multiple invalid element.

NonIntError(items + ' are not int type')

There is from timgeb's answer. There's no need to explain more.

Tony
  • 1,019
  • 2
  • 13
  • 25