Python win32com.client和“ with”语句

时间:2018-11-17 20:01:29

标签: python pywin32 with-statement excel.application

下午好,

我正在用Python编写一些ETL脚本,当前正在使用win32com.client在Excel中打开和刷新一些数据连接。

我的问题是:我应该使用 with 语句来打开/关闭“ Excel.Application”吗

import win32com.client
xl = win32com.client.DispatchEx("Excel.Application")

def wb_ref(file):
    xl.DisplayAlerts = False
    with xl.workbooks.open(file) as wb:
        wb.RefreshAll()
        wb.Save()

wb_ref('C:/Users/smugs/Documents/folder_a/workbooks/test.xlsx')

当我尝试过这种情况时,会发生异常,因此显然我没有正确使用它。

Traceback (most recent call last):
  File "C:/Users/smugs/Documents/Python Scripts/Work/km_jobs/utils/xl_conv.py", line 32, in <module>
    wb_ref( 'C:/Users/smugs/Documents/folder_a/workbooks/test.xlsx')
  File "C:/Users/smugs/Documents/Python Scripts/Work/km_jobs/utils/xl_conv.py", line 11, in wb_ref
    with xl.workbooks.open(file) as wb:
AttributeError: __enter__

还是我需要显式调用close命令

def wb_ref(file):
    xl.DisplayAlerts = False
    wb = xl.workbooks.open(file)
    wb.RefreshAll()
    wb.Save()
    wb.Close()

wb_ref('C:/Users/smugs/Documents/folder_a/workbooks/test.xlsx')

第二个示例是我一直在使用的示例,它可以正常工作。我想我只是想知道编写上述函数的更Python方式是什么。

(fyi-第一次申请者,长期读者)

1 个答案:

答案 0 :(得分:3)

由于AttributeError: __enter__不是context manager,所以您收到xl.workbooks.open错误,因此它不支持with语句。

如果要在代码中使用with语句,可以使用标准库中closing模块中的contextlib函数,如下所示:

from contextlib import closing

def wb_ref(file):
    xl.DisplayAlerts = False
    with closing(xl.workbooks.open(file)) as wb:
        wb.RefreshAll()
        wb.Save()

contextlib.closing将在close块中的代码完成执行后,自动对传递给它的对象调用with