0

I am new in Python and I did not find a clear method yet.

I have several functions (possibly hundreds) that I want to wrap in the same code over and over.

try:
    OneOfTheOneHundredFunctions()

except MY_ERROR as error:
    print('Error: I caught an error')

Do I have to specify the wrapper for each of the OneOfTheOneHundredFunctions()? In C++, I would do that with a macro, is there something similar in python?

imxitiz
  • 3,920
  • 3
  • 9
  • 33
Wing
  • 642
  • 2
  • 5
  • 16
  • 1
    could you add them all into a 101th function and call that function? – ti7 Jul 29 '21 at 14:19
  • is the idea just to continue after an error (specifically using an Exception handler) for each of the target functions? – ti7 Jul 29 '21 at 14:20
  • The idea is: if the function fails for some reason I would need to wait some time before doing something else. The script would run some code, then when the system is busy and cannot work it would wait some time, and then continue – Wing Jul 29 '21 at 14:22

4 Answers4

0

You can reference functions by their name, so you can collect them in some iterable

for index, fn in enumerate((  
    function1,
    function2,
    function3,
)):
    try:
        fn()
    except Exception as ex:
        print(f"ERROR: function {index} raised {repr(ex)}")

enumerate is just convenient here to get the index of the function in a tuple, but you can put the names into any iterable, like a dict and also name the functions (with some comment?)

functions_dict = {"check A": fn1, "check B": fn2, ...}
for comment, function in functions_dict.items():
    ...
ti7
  • 16,375
  • 6
  • 40
  • 68
0

You could essentially create a function with the wrapper, and pass in a pointer to the other functions you want. Inside the wrapper you would call the function that's pointed to.

def catch_error(my_function):
    try:
        my_function()
    except MY_ERROR as error:
        print('Error: I caught an error')

list_of_functions = [OneOfTheHundredFunctions, TwoOfTheHundredFunctions, ...]
for function in list_of_functions:
    catch_error(function)


# Calling functions out of order
catch_error(TwoOfTheHundredFunctions)
# Some more logic
catch_error(OneOfTheHundredFunctions)
nanotek
  • 2,959
  • 15
  • 25
  • this would work only if I knew right now the order in which I'd have to call all of the functions. I do not know that yet. I still need to do a script using several functions of a given API – Wing Jul 29 '21 at 14:26
  • @Wing The construct works the same, I just did it as a list here and iterate over the list. You would just call `catch_error` however your logic dictates – nanotek Jul 29 '21 at 14:29
  • @Wing I added how you could call the function outside of a loop (Given you said you are new to python) – nanotek Jul 29 '21 at 14:43
0

Functions and Exceptions are first-class members in Python, so you can simply pass them into another function that does the try/except block:

def try_to_run(function, error_to_catch, *args, **kwargs):
    try:
        return function(*args, **kwargs)
    except error_to_catch:
        print('Error: I caught an error')

def OneOfTheOneHundredFunctions():
    pass

MY_ERROR = ValueError

result = try_to_run(
    function=OneOfTheOneHundredFunctions, 
    error_to_catch=MY_ERROR,
)

Note that any additional arguments/keyword arguments passed to try_to_run are passed in to the actual function you're wrapping around the try/except (that's what the *args and **kwargs are for).

jfaccioni
  • 7,099
  • 1
  • 9
  • 25
  • So here I would have to define/pass al of the functions I want one at a time, and then pass each one (when I need it) to the try_to_run? – Wing Jul 29 '21 at 14:29
  • Yes, you just replace the lines where you would call `function01()`, `function02()`, `function03()`. `...` with `try_to_run(function01)`, `try_to_run(function02)`, `try_to_run(function03)`, `...`. – jfaccioni Jul 29 '21 at 14:30
  • Ok I have tested this approach with my use case (that has a slight complication not discussed here) and it seems to be spot on. Thanks! – Wing Jul 29 '21 at 15:26
0

If you have functions in separate file, or I think you may separate it. Then you can use this to get list of function from that module/file:
How to list all functions in a Python module? another answer same but I think some description.

from inspect import getmembers, isfunction
from my_project import my_module

list_of_functions = getmembers(my_module, isfunction)

And now you can follow OPs ideas.

Like @nanotek said :

def catch_error(my_function):
    try:
        my_function()
    except MY_ERROR as error:
        print('Error: I caught an error')

for function in list_of_functions:
    catch_error(function)
imxitiz
  • 3,920
  • 3
  • 9
  • 33
  • If you want to use each function with completely separate logic conditions then I don't think it will work for you. – imxitiz Jul 29 '21 at 14:46