如何确保在脚本失败时关闭xlwings连接?

问题描述 投票:0回答:1

我正试图开发一些与 xlwings 因为我需要用宏等操作一个xls文件。虽然关闭连接总是好的,但Excel是臭名昭著的,如果多个实例正在运行,它就会阻止访问。因此,我需要确保即使我的代码在上游某个地方失败,应用程序也能关闭。

我目前正在用一个 try 语句,跨越整个脚本,当它失败时调用 app.quit(). 但是这样就抑制了我的错误信息,使调试变得困难。所以我觉得一定有更好的办法。

在另一种情况下,我看到了 with 正在使用。我感觉它也适用于这里,但我不明白它是如何工作的,也不明白它在这种特定情况下如何工作。

import xlwings as xw

def myexcel():
    try:
        #connect to Excel app in the background
        excel = xw.App(visible=False)
        # open excel book
        wb = excel.books.open(str(file))
        # asign the active app so it can be closed later
        app = xw.apps.active

        # more code goes here 

    except:
        app.quit()

如何确保excel连接总是被关闭,不管用什么最有效的方法?with 是解决方法,我也希望能得到一个好的源头来了解更多关于这个概念。

python try-catch with-statement xlwings
1个回答
2
投票

正如你所提到的,你可以使用 with 声明和建立自己的 contextmanager. 下面是一个根据你的代码转换的例子。

import xlwings as xw

class MyExcelApp:
    def __init__(self):
        self.excel = xw.App(visible=False)

    def __enter__(self):
        return self.excel

    def __exit__(self, exc, value, traceback):
        # Handle your app-specific exceptions (exc) here
        self.excel.quit()
        return True   
        # ^ return True only if you intend to catch all errors in here.
        # Otherwise, leave as is and use try... except on the outside.

class MyExcelWorkbook:
    def __init__(self, xlapp, bookname):
        self.workbook = xlapp.books.open(bookname)

    def __enter__(self):
        return self.workbook

    def __exit__(self, exc, value, traceback):
        # Handle your workbook specific exceptions (exc) here
        # self.workbook.save()   # depends what you want to do here
        self.workbook.close()
        return True   
        # ^ return True only if you intend to catch all errors in here.
        # Otherwise, leave as is and use try... except on the outside.    

有了这个设置,你可以简单地这样调用它。

with MyExcelApp() as app:
    with MyExcelWorkbook(filename) as wb:
        # do something with wb

你也可以实现它 带发电机这将与另一个答案非常相似。 下面是一个简化版。

import xlwings as xw
from contextlib import contextmanager

@contextmanager
def my_excel_app():
    app = xw.App(visible=False)
    try:
        yield app

    except:  # <-- Add SPECIFIC app exceptions
        # Handle the errors

    finally:
        app.quit()

用法:

with my_excel() as app:
    wb = app.books.open(some_file)
    # do something...

1
投票

你做得很对 - 在这种情况下,使用 try 块是最好的方法。当你需要打开文件时,使用With语句是很好的,但是当你使用库用它自己的方式打开excel文件时,With语句就不适合你的情况了。

为了显示异常的细节,你可以修改你的代码如下。

import xlwings as xw

def myexcel():
    try:
        #connect to Excel app in the background
        excel = xw.App(visible=False)
        # open excel book
        wb = excel.books.open(str(file))
        # asign the active app so it can be closed later
        app = xw.apps.active

        # more code goes here 

    finally:
        app.quit()
    except Exception as e:
        print('exception catched: {}'.format(e))
        app.quit()
© www.soinside.com 2019 - 2024. All rights reserved.