Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are python Exceptions as class attributes a bad thing?

I find myself often wanting to structure my exception classes like this:

# legends.py
class Error(Exception): pass

class Rick(object):
    class Error(Error): pass
    class GaveYouUp(Error): pass
    class LetYouDown(Error): pass

class Michael(object):
    class Error(Error): pass
    class BlamedItOnTheSunshine(Error): pass
    class BlamedItOnTheMoonlight(Error): pass

I have only seen this pattern used in Django (DoesNotExist) and it makes so much sense. Is there anything I'm missing, why most people seem to favor top-level Exceptions?

edit I would use these classes for versatile granularity, e.g:

import legends

try:
    do_stuff()
except legends.Michael.Error:
    blame_it_on_the_boogie()
except legends.Rick.GaveYouUp:
    let_you_down()
except legends.Error:
    pass
except Exception as e:
    raise Hell()
like image 523
Jesse the Game Avatar asked Nov 13 '12 20:11

Jesse the Game


People also ask

Are exceptions bad in Python?

Simply put, if an exception or error is thrown, something's wrong. It may not be something very wrong, but creating, throwing, and catching errors and exceptions just for the sake of using goto statements is not a good idea, and it's rarely done.

Is exception a class in Python?

In Python, users can define custom exceptions by creating a new class. This exception class has to be derived, either directly or indirectly, from the built-in Exception class. Most of the built-in exceptions are also derived from this class.

What are the attributes of exception in Python?

A tuple of the argument values provided when the exception was created. Generally this is the error message associated with the exception. However, an exception can be created with a collection of values instead of a message string; these are collected into the args attribute.

What is the parent class of exception Python?

Practical Data Science using Python All exception classes are derived from the BaseException class. The code can run built in exceptions, or we can also raise these exceptions in the code. User can derive their own exception from the Exception class, or from any other child class of Exception class.


1 Answers

This is the exact pattern used by Django for certain ORM-related exceptions.

The advantage is that you can have an except clause which checks against a type accessed through an instance:

rick = Rick()

try:
   rick.roll()
except rick.GaveYouUp:
   never()
except rick.LetYouDown:
   never_ever()

This doesn't look that useful here, but if rick were a function parameter, then it would potentially be rather useful.

This is also extremely useful in writing generic code which raises the exceptions:

GoddamStar(object):
   def sing(self,tune):
       raise self.Error()

class Rick(GoddamStar):
    class Error(Error): pass
    class GaveYouUp(Error): pass
    class LetYouDown(Error): pass

class Michael(GoddamStar):
    class Error(Error): pass
    class BlamedItOnTheSunshine(Error): pass
    class BlamedItOnTheMoonlight(Error): pass

rick = Rick()

try:
   rick.sing()
except Rick.GaveYouUp:
   never()
except Michael.Error:
   never_ever()

Django's exceptions generally all derive from global base classes, so that you can also have a catch-all clause which still switches on a type of exception, in case your rick is of an unknown (or otherwise unprovided for) class.

The reason why this isn't much more common is that (a) it doesn't work in early-bound languages, which attract most of the book writers (b) it's moderately rare that this is useful to the user, and so application writers likely figure they aren't going to need it.

like image 79
Marcin Avatar answered Oct 13 '22 01:10

Marcin