# -*- coding: utf-8 -*-
# 作者:新手
__author__ = ‘Administrator‘
#py标准库之atexit 程序关闭回调
import atexit
#用于在注册程序正常关闭时调用函数,sys模块还提供了一个hook,sys.exitfunc, 不过这里只能注册一个函数,aatexit注册表有多个模块和库同时使用
#例子1:通过 register()注册一个函数
def all_done():
print ‘all_done()‘
print ‘registering‘
atexit.register(all_done)
print ‘registering‘
#由于种皮不做其他工作,会立即调用all_done()
#还可以注册多个函数,并向注册的函数传递参数,这对于妥善断开数据库连接,删除临时文件等是很有用处的,不用为需要翻译资源维护一个特殊列表,完全可以对每一个资源注册一个单独的清理函数
def clear1(name):
print ‘clear(%s)‘%name
atexit.register(clear1,‘abc‘)
atexit.register(clear1,‘123‘)
atexit.register(clear1,‘two‘)
#退出函数会按注册的逆序来调用,这个方法以模块导入顺序(相应地,就是注册其atext函数顺序)的逆序完成模块清理,这样会减少依赖冲突
#什么样的情况下不调用atext函数
"""
满足以下任何一个条件,就一举动调用atext函数
1:程序由于一个信号而中止
2:直接被调用os._exit()
3:检测到解释器发生一个致命错误
"""
#1信号
import os,signal,subprocess,time,sys
proc=subprocess.Popen(r‘G:\project\x1.py‘)
print ‘parent: pausing before seding signal 1...‘
time.sleep(1)
print ‘parent: pausing before seding signal 2...‘
os.kill(proc.pid,signal.SIGTERM)
#子程序建议一个atext回调,然后休眠,直到信号到来
#2
def not_called():
print ‘not called()‘
print ‘atexit handler‘
sys.stdout.flush()
atexit.register(not_called)
print ‘signal‘
sys.stdout.flush()
time.sleep(5)
#子程序不会打印嵌套在not_called()中的消息
#如果程序使用os._exit()就不会在调用atextit回调
def call():
print ‘call()‘
print ‘registering‘
atexit.register(call)
print ‘register‘
print ‘exit....‘
os._exit(0)
#如果要确保回调运行,可以在语句外运行来执行或者调用 sys.exit()使程序中止
def donw():
print ‘down()‘
print ‘registering‘
atexit.register(donw)
print ‘register‘
print ‘exit....‘
sys.exit()
#处理异常
#atexit回调中所产生的traceback会打印到控制台,最后产生异常会重新招聘,作为程序最后一个错误信息
def exit1(mess):
raise RuntimeError(mess)
atexit.register(exit1,‘one‘)
atexit.register(exit1,‘two‘)
#注册顺序会控制执行顺序,如果一个回调中某个错误引入另一个回调中一个错误(越先注册,越后调用),最后错误消息 可能并不是为用户显示最有用的错误信息
#官方标准库地址:https://docs.python.org/2.7/library/atexit.html?highlight=atexit#module-atexit