从Python中的另一个函数执行中断函数

时间:2014-07-30 05:40:41

标签: python interrupt

我有一个函数a执行某些任务,另一个函数b是对某些事件的回调。每当事件发生时,调用函数b,我希望能够中断函数a的执行。这两个函数都在同一个类中声明。

函数a不应该调用函数b。函数b是完全独立的,它是对外部事件的回调,例如"检测到用户面部"来自ROS:机器人操作系统。

我需要的是基本上类似Ctrl + C的东西,可以在Python中调用,只能中止目标函数而不是整个程序。

可以用Python完成吗?

3 个答案:

答案 0 :(得分:3)

我会做以下事情:

  • 定义自定义例外
  • 在适当的try / catch块中调用回调函数
  • 如果回调函数决定中断执行,它将引发异常,调用者将捕获它并根据需要处理它。

这是一些伪代码:

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

答案 1 :(得分:2)

通常建议不要使用异常调用进行流量控制。相反,请查看python stdlib的threading.Event,即使您只计划使用单个线程(即使最基本的Python程序至少使用一个线程)。

这个答案https://stackoverflow.com/a/46346184/914778很好地解释了如何调用一个函数(函数b)可以中断另一个函数(函数a)。

以下是一些重要的部分,从其他答案中总结出来。

设置线程库:

SELECT 
        CASE WHEN
            CAST((select sum(Total) from LettersTable LT
                        WHERE LT.ID = AT.ID
                        AND LT.Count > 5) 
                        AS INT) IS NULL             
            THEN 
                (select sum(Total) from LettersTable LT
                        WHERE LT.ID = AT.ID
                        AND LT.Count > 5) 
                        AS INT)
            ELSE  
                (select sum(Total) from LettersTable LT
                        WHERE LT.ID = AT.ID
                        AND LT.Count > 5) 
                        AS INT)
 FROM AlphabetTable AT

这是from threading import Event global exit exit = Event() 的一个很好的替代品,因为它可以是中断:

time.sleep(60)

此代码将执行,直到您将exit更改为“set”:

exit.wait(60)

这会导致while not exit.is_set(): do_a_thing() 停止等待,exit.wait(60)将返回exit.is_set()

True

这将再次启用执行,exit.set() 将返回exit.is_set()

False

答案 2 :(得分:0)

我使用了线程。

    import threading
class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        # Get lock to synchronize threads
        #threadLock.acquire()
        if self.name == 'a':
            function_a(self.name, self.counter, 3)
        if self.name == 'b':
            function_b(self.name, self.counter, 3)

def function_a(threadName, delay, counter):
    name = raw_input("Name")
    print name

def function_b(threadName, delay, counter):
    global thread1
    thread1.shutdown = True
    thread1._Thread__stop()

# Create new threads
thread1 = myThread(1, "a", 0)
thread2 = myThread(2, "b", 0)

# Start new Threads
thread1.start()
thread2.start()

function_a在thread1停止时停止执行