Exception handling of the same type separately in Python

Let's say I have the following four variables:

>>> f1 = (print, 1, 2 ,3 ,4) >>> f2 = (exit, 1, 2 ,3 ,4) >>> f3 = (1, 2, 3, 4) >>> f4 = 4 

In a hypothetical program, I expect that each of these variables will contain a tuple, the first element of which should be the name of the function, and the subsequent elements should be specified as parameters of the function in order.

I could call a function stored this way:

 >>> f1[0](*f1[1:]) 1 2 3 4 

However, most of these variables are not in an excluded format, and I would like to be able to encapsulate their call inside try / except blocks to handle these situations.

Now, even though function calls f2 , f3 and f4 break for a radically different reason, they all throw the same exception, TypeError :

 >>> f2[0](*f2[1:]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __call__() takes from 1 to 2 positional arguments but 5 were given >>> f3[0](*f3[1:]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not callable >>> f4[0](*f4[1:]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not subscriptable 

So, to do the general:

 try: f[0](*f[1:]) except TypeError: # handle exception 

Would not provide me with enough information to handle each exception.

What would be the proper way to distinguish between separate exceptions of the same type in Python?

+6
source share
1 answer

So you need to use a different calling method than function(*tuple) . The following is an example of a fun_apply function that calls a specific function with positional and keyword arguments. It adds an explicit check to make sure args is iterable and kwargs inherits from collection.Mapping .

 from collections import Mapping def fun_apply(f, args=None, kwargs=None): if args is None: args = [] if kwargs is None: kwargs = {} try: args = iter(args) except TypeError: # handle args being non-iterable pass if isinstance(kwargs, collections.Mapping): pass else: # handle kwargs being a non-mapping pass if hasattr(f, '__call__'): pass else: # handle f being non-callable pass try: f(*args, **kwargs) except TypeError as e: raise TypeError(e) 

Another option is to process the message string explicitly, but this can have unintended consequences, and the error messages themselves may vary between versions of Python.

+2
source

All Articles