Как пропустить одну часть итерации одного цикла в Python - PullRequest
0 голосов
/ 19 февраля 2019

Я создаю около 200 переменных в одной итерации цикла python (извлекаю поля из документов Excel и помещаю их в базу данных SQL) и пытаюсь что-то выяснить.

Скажем, одна итерация - это одна книга Excel, которую я зацикливаю в каталоге.Я извлекаю около 200 полей из каждой рабочей книги.

Если я извлекаю одно из этих полей (скажем, поле № 56 из 200), и оно имеет неправильный формат (допустим, дата была заполнена неправильнот. е. 31.09.2015, который не является реальной датой), и он ошибается в операции, которую я выполняю.

Я хочу, чтобы цикл пропустил эту переменную и приступил к созданию переменной # 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               

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Как и предполагалось, вы можете использовать несколько блоков 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 для повторения нескольких функций и передайте partial как замороженную функцию с аргументами.

Это может помочь вашему коду выглядеть аккуратно, не загромождаямного try блоков.Но лучший, более понятный способ - просто обработать поля, которые, как вы ожидаете, могут ошибаться по отдельности.

0 голосов
/ 19 февраля 2019

Итак, в основном вам нужно обернуть ваш 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)
0 голосов
/ 19 февраля 2019

Используйте несколько блоков 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
...