How to get outer class name from an inner class?

Jean-Michel Pichavant jeanmichel at sequans.com
Wed May 9 08:21:26 EDT 2012


John Gordon wrote:
> I'm trying to come up with a scheme for organizing exceptions in
> my application.
>
> Currently, I'm using a base class which knows how to look up the text
> of a specific error in a database table, keyed on the error class name.
>
> The base class looks like this:
>
> class ApplicationException(Exception):
>     """Base class for application-specific errors."""
>
>     def get_message(self):
>         """Return the error message associated with this class name."""
>
>         class_name = self.__class__.__name__
>         return UserMessage.objects.get(key=class_name).text
>
> And then I define a bunch of subclasses which all have different names:
>
> class QuestionTooShortError(NetIDAppsError):
>     """User entered a security question which is too short."""
>     pass
>
> class QuestionTooLongError(NetIDAppsError):
>     """User entered a security question which is too long."""
>     pass
>
> This scheme works, but I'd like to make it more streamlined.  Specifically,
> I'd like to group the classes underneath a parent class, like so:
>
> class Question(ApplicationException):
>
>     class TooShort(ApplicationException):
>         pass
>
>     class TooLong(ApplicationException):
>         pass
>
> This will make it easier in the future for organizing lots of sub-errors.
>
> My problem is this: the get_message() method in the base class only knows
> the current class name, i.e. "TooShort" or "TooLong".  But that's not
> enough; I also need to know the outer class name, i.e. "Question.TooShort"
> or "Question.TooLong".  How do I get the outer class name?
>
> Thanks,
>
>   

You're going way too much into details regarding your exceptions.
Basically, you need to create an exception class is at some point you 
need different handlers.
For instance,

try:
    whatever()
except Question.TooShort:
    dosomething()
except Question.TooLong:
    dosomethingelse()

But I'm not sure you really need this.

Try to keep it simple.

You fetch you exception message from a database, is that really required 
? Why can't you just write it in your code ?
Another problem is getting the database key from the class name, this 
makes difficult changing any class name, I'm not sure this is a good idea.

Anyway I'm not sure I'm helping here, providing more questions than answer.

What you could do :


class AppException(Exception): pass

class Question(AppException): pass
class TooShort(Question): pass
class TooLong(Question): pass

def getName(cls):
    if not hasattr(cls, '__base__'):
        raise ValueError('Not a new class style')   
    if cls is AppException:
        return cls.__name__
    return getName(cls.__base__)+'.' + cls.__name__

 > getName(TooShort)
< 'AppException.Question.TooShort'

This implies you're using only inheritance, not using class as 
ccontainer/namespace.

JM





More information about the Python-list mailing list