atexit:如何手动触发?

2024-03-28 11:03:00 发布

您现在位置:Python中文网/ 问答频道 /正文

当我运行python脚本时,我可以退出解释器,atexit将执行我注册的所有函数。你知道吗

现在,我正在使用airflow并希望触发atexit任务on_kill()(即,当我清除或杀死airflow中的dag节点时)。你知道吗

例如,在伪代码中,我需要能够:

class Foo(PythonOperator):
  ...
  def on_kill():
     # somehow, trigger atexit tasks without exiting the 
     # process entirely

atexit也不是必须的——我可以做别的事情。主要的一点是,在python上下文之外执行的某些内容需要以过程的方式终止,理想情况下,通过引用housing脚本来传递终止函数将是最后的手段(python并没有使这个特定的替代方法变得容易)。你知道吗


Tags: 函数代码脚本节点fooondef解释器
2条回答

如果我没有误解您的问题,您可以通过atexit._run_exitfuncs()触发在atexit中注册的所有函数:

import atexit


def do_something():
    print('I am doing some work')


def run_on_exit():
    print('I run on exit')


def do_something_else():
    print('I am doing more work')


if __name__ == '__main__':
    atexit.register(run_on_exit)
    do_something()
    atexit._run_exitfuncs()
    do_something_else()

输出显示触发已注册的退出函数不会停止程序流,而是允许运行更多函数。你知道吗

您可以对atexit模块进行修补-如下所示:

import atexit
from queue import LifoQueue


save_register = atexit.register
atexit_queue = LifoQueue()

def my_register(func, *args, **kwargs):
    save_register(func, *args, **kwargs)
    atexit_queue.put((func, args, kwargs))

atexit.register = my_register


if __name__ == '__main__':

    def func1():
        print('func1() called')

    def func2(arg):
        print(f'func2({arg}) called')

    def func3(arg, kwarg1=1, kwarg2='foo'):
        print(f'func3({arg}, kwarg1={kwarg1}, kwarg2={kwarg2!r}) called')

    atexit.register(func1)
    atexit.register(func2, 1)
    atexit.register(func3, 2, kwarg1=42, kwarg2='bar')

    print('Calling queued atexit functions:\n')
    while atexit_queue.qsize():
        func, args, kwargs = atexit_queue.get()
        atexit.unregister(func)  # Prevent it from being called again.
        func(*args, **kwargs)

输出:

Calling queued atexit functions:

func3(2, kwarg1=42, kwarg2='bar') called
func2(1) called
func1() called

相关问题 更多 >