Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interrupt function execution from another function in Python

I have a function a doing some tasks and another function b being a callback to some events. Whenever an event happens, function b is called and I would like to make it able to interrupt the execution of function a. Both functions are declared inside the same class.

Function a is not supposed to call function b. Function b is totally independent, it is a callback to an external event like "user face detected" coming from ROS: robot operating system.

what I need is basically something like Ctrl+C that can be called from within Python and which only aborts a targeted function and not the whole program.

Can this be done in Python?

like image 616
Mehdi Avatar asked Jul 30 '14 05:07

Mehdi


2 Answers

It's generally recommended not to use exception calling for flow-control. Instead, look to python stdlib's threading.Event, even if you only plan on using a single thread (even the most basic Python program uses at least one thread).

This answer https://stackoverflow.com/a/46346184/914778 has a good explanation of how calling one function (function b) could interrupt another (function a).

Here's a few important parts, summarized from that other answer.

Set up your threading libraries:

from threading import Event
global exit
exit = Event()

This is a good replacement for time.sleep(60), as it can be interrupt:

exit.wait(60)

This code will execute, until you change exit to "set":

while not exit.is_set():
    do_a_thing()

This will cause exit.wait(60) to stop waiting, and exit.is_set() will return True:

exit.set()

This will enable execution again, and exit.is_set() will return False:

exit.clear()
like image 95
Michael Innes Avatar answered Oct 18 '22 21:10

Michael Innes


I would do the following:

  • define a custom exception
  • call the callback function within an appropriate try/catch block
  • if the callback function decides to break the execution, it will raise exception and the caller will catch it and handle it as needed.

Here's some pseudo-code:

class InterruptExecution (Exception):
    pass

def function_a():
    while some_condition_is_true():
        do_something()
        if callback_time():
            try:
                function_b()
            except InterruptExecution:
                break
        do_something_else()
    do_final_stuff()


def function_b():
    do_this_and_that()
    if interruption_needed():
        raise (InterruptExecution('Stop the damn thing'))
like image 40
Boris Gorelik Avatar answered Oct 18 '22 22:10

Boris Gorelik