Justin
Justin

Reputation: 385

Why pass a string argument to raise Exception()

I'm working through a chapter on exceptions in Python and the author gives the following example, some different exceptions are stored in a list, one or none is chosen randomly and handled:

import random
some_exceptions = [ValueError, TypeError, IndexError, None]

try:
    choice = random.choice(some_exceptions)
    print(f'raising {choice}')
    if choice:
        raise choice('An Error') # Don't understand the need for the 'An Error' argument
except ValueError:
    print('Caught a ValueError')
except TypeError:
    print('Caught a TypeError')
except Exception as e:
    print(f'Caught some other error: {e.__class__.__name__}')
else:
    print('This code is called if there is no exception')
finally:
    print('This code is always called')

I don't understand the line raise choice('An Error'), the words 'An Error' are never output to the console and the example appears to work just as well with that line changed to raise choice(), is there any specific reason the author did this?

Upvotes: 1

Views: 2302

Answers (6)

Rishabh Kumar
Rishabh Kumar

Reputation: 2430

These both are type errors (in native python), but see how the custom message is different

>>> a = [1,2,3]
>>> a['d']

TypeError: list indices must be integers or slices, not str

>>> 1 in 'fs'

TypeError: 'in <string>' requires string as left operand, not int

And so, to generate a custom error message which is subset of an existing class you can do this:

>>> raise TypeError('meaningless type error')

TypeError: meaningless type error

Upvotes: 1

Serge Ballesta
Serge Ballesta

Reputation: 148965

It is just the common usage. Exceptions (derived from BaseException) have an args member which contains the parameters passed at creation time, so they can accept 0 to n parameters. Nevertheless the doc for BaseException.args says (emphasize mine):

The tuple of arguments given to the exception constructor. Some built-in exceptions (like OSError) expect a certain number of arguments and assign a special meaning to the elements of this tuple, while others are usually called only with a single string giving an error message.

Upvotes: 1

Siddharth Agrawal
Siddharth Agrawal

Reputation: 3146

I think you are confused how the raise command works. It takes a class which already has some inbuilt some stuff like an Exception class. It cannot raise exception on any class. If you need to raise that message, go about like

import random
some_exceptions = [ValueError, TypeError, IndexError, None]

try:
    choice = random.choice(some_exceptions)
    print(f'raising {choice}')
    if choice:
        raise Exception('An Error') # Don't understand the need for the 'An Error' argument
except ValueError:
    print('Caught a ValueError')
except TypeError:
    print('Caught a TypeError')
except Exception as e:
    print(f'Caught some other error: {e.__class__.__name__}')
else:
    print('This code is called if there is no exception')
finally:
    print('This code is always called')

Upvotes: 1

guidot
guidot

Reputation: 5333

Exceptions are classes. If you write your own (deriving e.g. from ValueError) the constructor of instance creation - this is what do by writing ValueError() - may store this string to be output by the __str__ method of the exception. So if the exception type is insufficient for pinpointing the reason the string argument may prove useful.

Upvotes: 1

Mario Khoury
Mario Khoury

Reputation: 392

When you use Try catch in python in this way:

choice = ValueError
try:
    raise choice('An Error')
except ValueError as e:
    print(e)

You will get "An Error" printed it is useful to customize output error so you can know where the error happened like so:

choice = ValueError
a = int(input("Enter a number a"))
b = int(input("Enter a number b"))
try:
    error = "No error"
    if a == 0:
        error = "a is Null"
    if b == 0:
        error = "b is Null"
    raise choise(error)
except ValueError as e:
    print(e)

In this code you can track From where the error comes from if you do for example a division by a or b and you get a Null division error

Upvotes: 1

Dyno Fu
Dyno Fu

Reputation: 9044

Exceptions are classes too. the string are parameter passed to the class.

In [10]: help(ValueError)

In [11]: v = ValueError("value is not accepted.")

In [12]: v
Out[12]: ValueError('value is not accepted.')

In [13]: v.args
Out[13]: ('value is not accepted.',)

Upvotes: 4

Related Questions