I have an unavoidable situation that looks like this (simplified):
FUNCTION_TO_CALL = y # can be either y or z
def x(*args, **kargs):
FUNCTION_TO_CALL(args, kargs)
def y(foo, bar=None):
if foo == bar: # actually not this stupid
raise TypeError()
else:
pass
def z(foo, bar, baz=None):
pass
Horribly ugly, I know. :(
But, at any rate, I need to be able to distinguish between a TypeError being raised in y
because *args
doesn't have an开发者_Go百科ything in it or having too much in it (thus not having enough arguments or too many)/bad kwargs
or because foo == bar
.
In the actually setting, there are many more functions that can be called than two, not all of which have the code open to them.
Thanks so much!
You could always make your own exceptions subclassing TypeError, and use them individually.
class TooManyArgumentsError(TypeError):
pass
class EqualityError(TypeError):
pass
Matt Billenstein's comment on Keith Morrow's answer is the right way to do this. But alternatively, if for some bizarre reason you can't even do that, you could also look at the inspect
module.
try: ugly()
except TypeError as e:
stack = inspect.stack()
[...look at the stack...]
Info about the inspect module.
To elaborate on the "wrapping" question: assuming you have control over what functions are available to be assigned to FUNCTION_TO_CALL
, create y_better
def y_better(foo, bar=None):
try: y(foo, bar)
except TypeError:
if foo == bar: # detect foobar condition
raise FoobarError()
else: # not foobar, so re-raise the exception
raise
This means foo == bar is being tested twice, but given your restrictions, I don't see a better way to do it.
Define a custom exception:
class yTypeError(TypeError): pass
then raise this in y() and only in y()
精彩评论