我正试图开发一些与 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
是解决方法,我也希望能得到一个好的源头来了解更多关于这个概念。
正如你所提到的,你可以使用 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...
你做得很对 - 在这种情况下,使用 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()