如何在 Python 中跳过单个循环迭代的一部分

How to skip one part of a single loop iteration in Python

我在 python 循环的单次迭代中创建了大约 200 个变量(从 excel 文档中提取字段并将它们推送到 SQL 数据库)并且我正在尝试弄清楚一些事情。

假设单个迭代是我在目录中循环访问的单个 Excel 工作簿。我正在从每个工作簿中提取大约 200 个字段。

如果我提取的其中一个字段(比如说 200 个字段中的第 56 个字段)格式不正确(比如说日期填写错误,即 9/31/2015,这不是真实的date) 并且我正在执行的操作出错。

我希望循环跳过该变量并继续创建变量 #57。我不希望循环完全进入下一次迭代或工作簿,我只是希望它忽略该变量上的错误并继续处理该单循环迭代的其余变量。

我将如何做这样的事情?

在此示例代码中,我想继续提取 "PolicyState",即使 ExpirationDate 有错误。

一些示例代码:

import datetime as dt
import os as os
import xlrd as rd

files = os.listdir(path)

for file in files: #Loop through all files in path directory  
            filename = os.fsdecode(file) 
            if filename.startswith('~'): 
                continue

            elif filename.endswith( ('.xlsx', '.xlsm') ): 
                try:
                    book = rd.open_workbook(os.path.join(path,file)) 
                except KeyError:
                    print ("Error opening file for "+ file) 
                    continue

                    SoldModelInfo=book.sheet_by_name("SoldModelInfo")
                    AccountName=str(SoldModelInfo.cell(1,5).value)
                    ExpirationDate=dt.datetime.strftime(xldate_to_datetime(SoldModelInfo.cell(1,7).value),'%Y-%m-%d')
                    PolicyState=str(SoldModelInfo.cell(1,6).value)
                    print("Insert data of " + file +" was successful")
            else:
               continue               

使用多个 try 块。将每个可能出错的解码操作包装在它自己的 try 块中以捕获异常,做一些事情,然后继续下一个。

            try:
                book = rd.open_workbook(os.path.join(path,file)) 
            except KeyError:
                print ("Error opening file for "+ file) 
                continue

            errors = []

            SoldModelInfo=book.sheet_by_name("SoldModelInfo")
            AccountName=str(SoldModelInfo.cell(1,5).value)
            try:
                ExpirationDate=dt.datetime.strftime(xldate_to_datetime(SoldModelInfo.cell(1,7).value),'%Y-%m-%d')
            except WhateverError as e:
                # do something, maybe set a default date?
                ExpirationDate = default_date
                # and/or record that it went wrong?
                errors.append( [ "ExpirationDate", e ])
            PolicyState=str(SoldModelInfo.cell(1,6).value)
            ...
            # at the end
            if not errors:
                print("Insert data of " + file +" was successful")
            else:
                # things went wrong somewhere above. 
                # the contents of errors will let you work out what

按照建议,您可以在每个提取变量上使用多个 try 块,或者您可以使用自己的自定义函数来简化它,为您处理 try

from functools import reduce, partial

def try_funcs(cell, default, funcs):
    try:
        return reduce(lambda val, func: func(val), funcs, cell)
    except Exception as e:
        # do something with your Exception if necessary, like logging.
        return default

# Usage:

AccountName = try_funcs(SoldModelInfo.cell(1,5).value, "some default str value", str)
ExpirationDate = try_funcs(SoldModelInfo.cell(1,7).value), "some default date", [xldate_to_datetime, partial(dt.datetime.strftime, '%Y-%m-%d')])
PolicyState = try_funcs(SoldModelInfo.cell(1,6).value, "some default str value", str)

这里我们使用reduce to repeat multiple functions, and pass partial作为带参数的冻结函数。

这可以帮助您的代码看起来整洁,而不会因大量 try 块而变得混乱。但更好、更明确的方法是单独处理您预计可能会出错的字段。

所以,基本上您需要将 xldate_to_datetime() 调用包装到 try ... except

import datetime as dt

v = SoldModelInfo.cell(1,7).value

try:
    d = dt.datetime.strftime(xldate_to_datetime(v), '%Y-%m-%d')
except TypeError as e:
    print('Could not parse "{}": {}'.format(v, e)