如何获取Python3中已注册的atexit函数列表?

Cha*_*net 3 python python-3.x

在Python中,我可以使用atexit模块注册要在Python退出时执行的功能。有没有办法检索已注册的退出处理程序列表?

小智 8

这是访问注册函数(可调用对象)的纯 python 方法,但不是访问它们将使用的参数。这有点黑客,但对于调试等,它会做得很好:

Python 3.5.3 (default, Jul  9 2020, 13:00:10) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import atexit
>>> class Capture:
...     def __init__(self):
...         self.captured = []
...     def __eq__(self, other):
...         self.captured.append(other)
...         return False
... 
>>> c = Capture()
>>> atexit.unregister(c)
>>> print(c.captured)
[<function <lambda> at 0x7fc47631d730>, <built-in function write_history_file>]
>>> atexit.unregister(c.captured[0])  # this will work
Run Code Online (Sandbox Code Playgroud)

它是如何工作的:如文档所述,从回调列表中atexit.unregister(c)删除任何出现的事件c。它通过依次比较每个回调与cfor 相等来实现。这导致 call c.__eq__(other)other作为回调(这个调用永远不会被跳过,因为相反的方式 raises NotImplemented)。Capture.__eq__然后复制它的参数。

  • 我喜欢这个解决方案,非常聪明。 (2认同)

nic*_*ell 7

这是@BCarvello 以函数形式提供的解决方案:

import atexit


def get_atexit_functions():
    funs = []

    class Capture:
        def __eq__(self, other):
            funs.append(other)
            return False

    c = Capture()
    atexit.unregister(c)
    return funs
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 5

在Python 2中,该模块仍然只能作为Python使用,该atexit模块具有一个半私有列表:

atexit._exithandlers
Run Code Online (Sandbox Code Playgroud)

包含所有已注册的退出处理程序。

在Python 3中,该模块已用C重新编码,并且该列表不再可用,因此恐怕对于Python 3而言,您很不走运。

您必须将Python 2纯Python版本移植到Python 3,并确保使用它而不是C版本来重新访问列表。