将单个语句包装在 try except block 中的 Python 干净方法

标签 python excel vba com try-catch

我目前正在使用 com 对 Excel 进行一些 Python 自动化。它功能齐全,可以做我想做的事,但我发现了一些令人惊讶的事情。有时,我使用的某些 Excel 命令会无缘无故地失败并出现异常。其他时候,他们会工作。

在我正在做的事情的 VB 等效代码中,这个问题显然被认为是正常的,并且用 On Error Resume Next 语句覆盖。当然,Python 没有 said 语句。

我不能在 try except 循环中包含整个集合,因为它可能会在中途“失败”并且无法正确完成。那么,将几个独立的语句包装到一个 try except block 中的 pythonic 方法是什么?具体来说,比以下更清洁的东西:

try:
   statement
except:
   pass
try:
   statement
except:
   pass

相关代码是 excel.Selection.Borders 位。

def addGridlines(self, infile, outfile):
    """convert csv to excel, and add gridlines"""
    # set constants for excel
    xlDiagonalDown = 5
    xlDiagonalUp = 6
    xlNone = -4142
    xlContinuous = 1
    xlThin = 2
    xlAutomatic = -4105
    xlEdgeLeft = 7
    xlEdgeTop = 8
    xlEdgeBottom = 9
    xlEdgeRight = 10
    xlInsideVertical = 11
    xlInsideHorizontal = 12
            # open file
    excel = win32com.client.Dispatch('Excel.Application')
    workbook = excel.Workbooks.Open(infile)
    worksheet = workbook.Worksheets(1)

    # select all cells
    worksheet.Range("A1").CurrentRegion.Select()
    # add gridlines, sometimes some of these fail, so we have to wrap each in a try catch block
    excel.Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    excel.Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    excel.Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    excel.Selection.Borders(xlEdgeLeft).LineStyle = xlContinuous
    excel.Selection.Borders(xlEdgeLeft).Weight = xlThin
    excel.Selection.Borders(xlEdgeLeft).ColorIndex = xlAutomatic
    excel.Selection.Borders(xlEdgeTop).LineStyle = xlContinuous
    excel.Selection.Borders(xlEdgeTop).Weight = xlThin
    excel.Selection.Borders(xlEdgeTop).ColorIndex = xlAutomatic
    excel.Selection.Borders(xlEdgeBottom).LineStyle = xlContinuous
    excel.Selection.Borders(xlEdgeBottom).Weight = xlThin
    excel.Selection.Borders(xlEdgeBottom).ColorIndex = xlAutomatic
    excel.Selection.Borders(xlEdgeRight).LineStyle = xlContinuous
    excel.Selection.Borders(xlEdgeRight).Weight = xlThin
    excel.Selection.Borders(xlEdgeRight).ColorIndex = xlAutomatic
    excel.Selection.Borders(xlInsideVertical).LineStyle = xlContinuous
    excel.Selection.Borders(xlInsideVertical).Weight = xlThin
    excel.Selection.Borders(xlInsideVertical).ColorIndex = xlAutomatic
    excel.Selection.Borders(xlInsideHorizontal).LineStyle = xlContinuous
    excel.Selection.Borders(xlInsideHorizontal).Weight = xlThin
    excel.Selection.Borders(xlInsideHorizontal).ColorIndex = xlAutomatic
    # refit data into columns
    excel.Cells.Select()
    excel.Cells.EntireColumn.AutoFit()
    # save new file in excel format
    workbook.SaveAs(outfile, FileFormat=1)
    workbook.Close(False)
    excel.Quit()
    del excel

更新:

也许需要对错误位进行一些解释。在我的测试机器上使用相同的代码在同一个文件上运行两次相同的代码,产生相同的结果。一次运行会为每个 xlInsideVertical 行抛出异常。另一个为每个 xlInsideHorizo​​ntal 抛出异常。最后,第三次运行完全没有异常。

据我所知,Excel 认为这是正常行为,因为我正在克隆由 excel 的宏生成器构建的 VB 代码,而不是一个人生成的 VB 代码。当然,这可能是一个错误的假设。

它会在每一行都包含在一个 try except block 中运行我只是想要更短和更明显的东西,因为 20 行包含在他们自己的 try catch 循环中只是在以后自找麻烦。

更新2:

这是用于测试的经过清理的 CSV 文件:gist file

结论:

Vsekhar 提供的答案是完美的。它抽象出异常抑制,以便以后,如果有时间,我可以在异常发生时实际处理它们。它还允许记录异常,这样它们就不会消失,不会停止其他异常,并且足够小,可以在六个月后轻松管理。

最佳答案

考虑抽象化抑制。对于 Aaron 的观点,一般不要吞下异常。

class Suppressor:
    def __init__(self, exception_type):
        self._exception_type = exception_type

    def __call__(self, expression):
        try:
            exec expression
        except self._exception_type as e:
            print 'Suppressor: suppressed exception %s with content \'%s\'' % (type(self._exception_type), e)
            # or log.msg('...')

然后,在当前代码的回溯中准确记录引发的异常,并为该异常创建一个 Suppressor:

s = Suppressor(excel.WhateverError) # TODO: put your exception type here
s('excel.Selection.Borders(xlDiagonalDown).LineStyle = xlNone')

这样您就可以逐行执行(因此您的回溯仍然会有帮助),并且您只抑制了您明确想要的异常。其他异常照常传播。

关于将单个语句包装在 try except block 中的 Python 干净方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7271245/

相关文章:

vba - Refresh All 没有触发 QueryTable 的 BeforeRefresh 事件 - 为什么?

excel - 从单元格中删除内容,如果 IsNumber = False

python - 如何在保持分辨率的同时将 2D float numpy 数组无损保存到灰度图像中?

python - 将相同的函数与不同的参数组合起来 - Python

javascript - 无法使用 React 发送有效请求(它正在与curl一起使用)

python - 使用 Python 重构 CSV 文件

vba - 在多列列表框顶部添加项目

excel - 列中单元格的大写字母

vba - 编译器错误: User-defined types not defined

c# - VBA 中的 VSTO : AddIn. 对象有时返回 Nothing (null)