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