开发者

Distinguishing between same exception by where it was called

开发者 https://www.devze.com 2023-02-06 00:34 出处:网络
I have an unavoidable situation that looks like this (simplified): FUNCTION_TO_CALL = y # can be either y or z

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()

0

精彩评论

暂无评论...
验证码 换一张
取 消