__del__ __exist__ atexit 退出处理器
redis/client.py
def __exit__(self, exc_type, exc_value, traceback):
self.reset()
def __del__(self):
try:
self.reset()
except Exception:
pass
__del__ __exist__
atexit — Exit handlers — Python 3.12.5 documentation https://docs.python.org/3/library/atexit.html
atexit
— Exit handlers
The atexit
module defines functions to register and unregister cleanup functions. Functions thus registered are automatically executed upon normal interpreter termination. atexit
runs these functions in the reverse order in which they were registered; if you register A
, B
, and C
, at interpreter termination time they will be run in the order C
, B
, A
.
Note: The functions registered via this module are not called when the program is killed by a signal not handled by Python, when a Python fatal internal error is detected, or when os._exit()
is called.
Note: The effect of registering or unregistering functions from within a cleanup function is undefined.
Changed in version 3.7: When used with C-API subinterpreters, registered functions are local to the interpreter they were registered in.
- atexit.register(func, *args, **kwargs)
-
Register func as a function to be executed at termination. Any optional arguments that are to be passed to func must be passed as arguments to
register()
. It is possible to register the same function and arguments more than once.At normal program termination (for instance, if
sys.exit()
is called or the main module’s execution completes), all functions registered are called in last in, first out order. The assumption is that lower level modules will normally be imported before higher level modules and thus must be cleaned up later.If an exception is raised during execution of the exit handlers, a traceback is printed (unless
SystemExit
is raised) and the exception information is saved. After all exit handlers have had a chance to run, the last exception to be raised is re-raised.This function returns func, which makes it possible to use it as a decorator.
Warning
Starting new threads or calling
os.fork()
from a registered function can lead to race condition between the main Python runtime thread freeing thread states while internalthreading
routines or the new process try to use that state. This can lead to crashes rather than clean shutdown.Changed in version 3.12: Attempts to start a new thread or
os.fork()
a new process in a registered function now leads toRuntimeError
.
- atexit.unregister(func)
-
Remove func from the list of functions to be run at interpreter shutdown.
unregister()
silently does nothing if func was not previously registered. If func has been registered more than once, every occurrence of that function in theatexit
call stack will be removed. Equality comparisons (==
) are used internally during unregistration, so function references do not need to have matching identities.
atexit
Example
The following simple example demonstrates how a module can initialize a counter from a file when it is imported and save the counter’s updated value automatically when the program terminates without relying on the application making an explicit call into this module at termination.
try:
with open('counterfile') as infile:
_count = int(infile.read())
except FileNotFoundError:
_count = 0
def incrcounter(n):
global _count
_count = _count + n
def savecounter():
with open('counterfile', 'w') as outfile:
outfile.write('%d' % _count)
import atexit
atexit.register(savecounter)
Positional and keyword arguments may also be passed to register()
to be passed along to the registered function when it is called:
def goodbye(name, adjective):
print('Goodbye %s, it was %s to meet you.' % (name, adjective))
import atexit
atexit.register(goodbye, 'Donny', 'nice')
# or:
atexit.register(goodbye, adjective='nice', name='Donny')
Usage as a decorator:
import atexit
@atexit.register
def goodbye():
print('You are now leaving the Python sector.')
This only works with functions that can be called without arguments.
atexit --- 退出处理器 — Python 3.12.5 文档 https://docs.python.org/zh-cn/3/library/atexit.html
atexit
--- 退出处理器
atexit
模块定义了清理函数的注册和反注册函数. 被注册的函数会在解释器正常终止时执行. atexit
会按照注册顺序的*逆序*执行; 如果你注册了 A
, B
和 C
, 那么在解释器终止时会依序执行 C
, B
, A
.
注意: 通过该模块注册的函数, 在程序被未被 Python 捕获的信号杀死时并不会执行, 在检测到 Python 内部致命错误以及调用了 os._exit()
时也不会执行.
注意: 在清理函数内部注册或注销函数可能产生的影响是未定义的。
在 3.7 版本发生变更: 当配合 C-API 子解释器使用时,已注册函数是它们所注册解释器中的局部对象。
- atexit.register(func, *args, **kwargs)
-
将 func 注册为终止时执行的函数. 任何传给 func 的可选的参数都应当作为参数传给
register()
. 可以多次注册同样的函数及参数.在正常的程序终止时 (举例来说, 当调用了
sys.exit()
或是主模块的执行完成时), 所有注册过的函数都会以后进先出的顺序执行. 这样做是假定更底层的模块通常会比高层模块更早引入, 因此需要更晚清理.如果在 exit 处理器执行期间引发了异常,将会打印回溯信息 (除非引发的是
SystemExit
) 并且异常信息会被保存。 在所有 exit 处理器都获得运行机会之后,所引发的最后一个异常会被重新引发。这个函数返回 func 对象,可以把它当作装饰器使用。
警告
启动新线程或从已注册的函数调用
os.fork()
可能导致主 Python 运行时线程释放线程状态而内部threading
例程或新进程试图使用该状态之间的竞争条件。 这会造成程序崩溃而不是正常关闭。在 3.12 版本发生变更: 现在尝试启动新线程或在已注册的函数中
os.fork()
新进程会导致RuntimeError
。
- atexit.unregister(func)
-
将 func 移出当解释器关闭时要运行的函数列表。 如果 func 之前未被注册则
unregister()
将静默地不做任何事。 如果 func 已被注册一次以上,则该函数每次在atexit
调用栈中的出现都将被移除。 当取消注册时会在内部使用相等性比较 (==
),因而函数引用不需要具有匹配的标识号。
atexit
示例
以下简单例子演示了一个模块在被导入时如何从文件初始化一个计数器,并在程序终结时自动保存计数器的更新值,此操作不依赖于应用在终结时对此模块进行显式调用。:
try:
with open('counterfile') as infile:
_count = int(infile.read())
except FileNotFoundError:
_count = 0
def incrcounter(n):
global _count
_count = _count + n
def savecounter():
with open('counterfile', 'w') as outfile:
outfile.write('%d' % _count)
import atexit
atexit.register(savecounter)
位置和关键字参数也可传入 register()
以便传递给被调用的已注册函数:
def goodbye(name, adjective):
print('Goodbye %s, it was %s to meet you.' % (name, adjective))
import atexit
atexit.register(goodbye, 'Donny', 'nice')
# or:
atexit.register(goodbye, adjective='nice', name='Donny')
作为 decorator: 使用:
import atexit
@atexit.register
def goodbye():
print('You are now leaving the Python sector.')
只有在函数不需要任何参数调用时才能工作.
https://docs.python.org/3/reference/datamodel.html
def __exit__(self, exc_type, exc_value, traceback):
self.reset()
def __del__(self):
try:
self.reset()
except Exception:
pass