args attribute of Exception objects
Bengt Richter
bokr at oz.net
Tue Apr 12 06:19:07 EDT 2005
On 12 Apr 2005 01:57:31 -0700, sdementen at hotmail.com (Sebastien de Menten) wrote:
>Thank you guys for those good advices (and the very interesting
>example of AST hacking).
>
>However, this was an example of use for Exception.args. It does not
>alleviate my concerns about the fact that the args attribute is poorly
>designed for standard Exceptions.
>It is as if the Exception design was only made for end users (display
>of a string in an interpreter) without thinking about original ways to
>use them :-)
>
Look into it some more ;-)
Have you thought of subclassing Exception for your own purpose?
You can override the base exception class's Exception.__init__
which UIAM effectively does
def __init__(self, *args):
self.args = args
and no more. Using an existing special purpose exception like NameError
(IIRC seeing that correctly) to carry info for you is pretty weird ;-)
Here is a subclass that takes what would be e.args[0] and delivers it
instead as e.answer (well, "e" is "retans" below ;-)
>>> class BailingOutWithAnswer(Exception):
... def __init__(self, answer):
... self.answer = answer
...
>>> for ans in ['string', 123, 4.5, 67L, 8+9j,
... type('MyClass',(),{}), type('MyInst',(),{})()]:
... try: raise BailingOutWithAnswer(ans)
... except BailingOutWithAnswer, retans:
... print '%r -> retans.answer: %r' %(ans, retans.answer)
...
'string' -> retans.answer: 'string'
123 -> retans.answer: 123
4.5 -> retans.answer: 4.5
67L -> retans.answer: 67L
(8+9j) -> retans.answer: (8+9j)
<class '__main__.MyClass'> -> retans.answer: <class '__main__.MyClass'>
<__main__.MyInst object at 0x02EF14EC> -> retans.answer: <__main__.MyInst object at 0x02EF14EC>
It's the easiest thing in the world to define a minimal Exception subclass to give you
back in e.args whatever you pass it as args when you raise it. Obviously I could have used
a table of arg tuples and just raise XEasy(*argtuples[i]) instead of separating them out,
but I wanted to show how plain raise expression syntax with
different numbers of arguments map to e.args.
>>> class XEasy(Exception): pass
...
>>> for i in xrange(7):
... try:
... if i==0: raise XEasy(123)
... elif i==1: raise XEasy(4.5, 67L)
... elif i==2: raise XEasy(*'this may seem tricky ;-)'.split())
... elif i==3: raise XEasy, 'usual ordinary message form'
... elif i==4: raise XEasy(8+9j, type('AClass',(),{}))
... elif i==5: raise XEasy(type('AClass',(),{})(),'<=[class instance]')
... elif i==6: raise XEasy('--------------------------------------------')
... except XEasy, e:
... print e.args
...
(123,)
(4.5, 67L)
('this', 'may', 'seem', 'tricky', ';-)')
('usual ordinary message form',)
((8+9j), <class '__main__.AClass'>)
(<__main__.AClass object at 0x02EF166C>, '<=[class instance]')
('--------------------------------------------',)
Oops, left out the no-arg raises
>>> try: raise XEasy
... except XEasy, e: print e.args
...
()
>>> try: raise XEasy()
... except XEasy, e: print e.args
...
()
Did I misunderstand the problem again?
Regards,
Bengt Richter
More information about the Python-list
mailing list