4

I am currently working through Learning Python by Mark Lutz and David Ascher and I have come across a section of code that keeps bringing up errors. I am aware that that book was written with Python 2 in mind unlike the Pyhton 3 I am using. I was wondering if anyone knew a solution to my problem as I have looked everywhere but I have been unable to find a solution .

.........................

MyBad = 'oops'

def stuff( ):
    raise MyBad

try:
    stuff( )
except MyBad:
    print('got it')
Right leg
  • 16,080
  • 7
  • 48
  • 81
user8048576
  • 63
  • 1
  • 1
  • 7
  • 3
    What error do you get here? On python 3 I get: `TypeError: catching classes that do not inherit from BaseException is not allowed` – EdChum May 22 '17 at 14:13
  • I knew Python 2 allowed any object to be raised as an exception, but never knew [the extent to which `raise` supported it](https://docs.python.org/2.7/reference/simple_stmts.html#raise). – chepner May 22 '17 at 14:18

2 Answers2

14

Basically, MyBad is not an exception, and the raise statement can only be used with exceptions.

To make MyBad an exception, you must make it extend a subclass of Exception. For instance, the following will work:

class MyBad(Exception):
    pass

def stuff( ):
    raise MyBad

try:
    stuff( )
except MyBad:
    print('got it')

Output:

got it

However, it's better to raise an instance of an exception class, rather than the class itself, because it allows the use of parameters, usually describing the error. The following example illustrates this:

class MyBad(Exception):
    def __init__(self, message):
        super().__init__()
        self.message = message

def stuff(message):
    raise MyBad(message)

try:
    stuff("Your bad")
except MyBad as error:
    print('got it (message: {})'.format(error.message))

Output:

got it (Your bad)
Right leg
  • 16,080
  • 7
  • 48
  • 81
2

You cannot raise a custom exception without creating a class (at least an empty one).

You can add custom text as you want by using also an __init__ function instead of pass:

class MyBad(Exception):
    pass
    # def __init__(self, txt):
    #     print(txt)

def stuff( ):
     raise MyBad('test')

try:
    stuff( )
except MyBad:
    print('got it')

If you use pass, you will have :

got it

If you use the __init__() in comment, you will have

test and got it

Nicolas M.
  • 1,472
  • 1
  • 13
  • 26