IronPython - sys.exit() 时的资源正确释放

1 投票
2 回答
779 浏览
提问于 2025-04-17 11:09

当我调用 sys.exit() 时,如何正确结束 Python 脚本是最好的方法?

比如我有一个应用程序,它做了以下事情:

  • 打开了一个日志文件
  • 连接了一些 USB 设备
  • 决定是时候关闭应用程序了
  • 调用 sys.exit(-1)
  • (或者也可以抛出一个严重的异常,但我更喜欢第一种方式,因为我写的代码有些地方会捕获所有异常,这样会阻止我的退出异常...)

然后我需要一个 finalize() 函数,它会在退出解释器之前被调用。这个 finalize() 函数会按照顺序释放 USB 设备并关闭日志文件。

我尝试过使用 def del,但在调用 sys.exit 时这个函数并不会被调用,而且我也无法控制 _del_ 的调用顺序。

有没有什么办法可以解决我的问题?还是说我必须这样做:

  1. 在最上面使用 try-catch-finally
  2. 用某个特定的异常来退出
  3. 在每个异常捕获中明确指定我捕获的内容?

2 个回答

0

好的,我找到了最适合我的答案:

import sys
try:
  print "any code: allocate files, usb gadets etc "
  try:
    sys.exit(-1) # some severe error occure
  except Exception as e:
    print "sys.exit is not catched:"+str(e)
  finally:
    print "but all sub finallies are done"
  print "shall not be executed when sys.exit called before"
finally:
  print "Here we can properly free all resources in our preferable order"
  print "(ie close log file at the end after closing all gadgets)"

关于推荐的解决方案 atexit - 听起来不错,但在我的 Python 2.6 中并不好用。我试过这个:

import sys
import atexit

def myFinal():
  print "it doesn't print anything in my python 2.6 :("

atexit.register(myFinal)

print "any code"
sys.exit(-1) # is it pluged in?
print "any code - shall not be execute"

至于 Wrapper 解决方案 - 确实是最炫的,但老实说,我也说不出它到底好在哪里...

import sys
class mainCleanupWrapper(object):
    def __enter__(self):
        print "preallocate resources optionally"

    def __exit__(self, type, value, traceback):
        print "I release all resources in my order"

with mainCleanupWrapper() as whatsThisNameFor:
        print "ok my unchaged code with any resources locking"
        sys.exit(-1)
        print "this code shall not be executed" 

我找到了我的解决方案 - 不过老实说,Python 似乎变得越来越臃肿了...

1

看看Python中的with语句。

class UsbWrapper(object):
    def __enter__(self):
        #do something like accessing usb_gadget (& acquire lock on it)
        #usb_gadget_handle = open_usb_gadget("/dev/sdc")
        #return usb_gadget_handle

    def __exit__(self, type, value, traceback):
        #exception handling goes here
        #free the USB(lock) here

with UsbWrapper() as usb_device_handle:
        usb_device_handle.write(data_to_write)

无论代码是出错了还是正常运行,USB锁都会被释放。

撰写回答