Сгущение повторяющихся операторов try-except в python

У меня есть скрипт, который просит пользователя ввести много дат, в основном в функциях, подобных приведенной ниже. Они должны учитывать недопустимые форматы даты:

import numpy as np
import pandas as pd
import xlwings as xw
import datetime as dtt

def week_init():
        """Creates an initial week datetime and determines what the checking cutoff
        'beforeday' to be used in Stage 2 is."""
        week = input('Week to check: MM/DD/YYYY\n')
        switch = 1
        while switch == 1:
            try:
                week = dtt.datetime.strptime(week,'%m/%d/%Y') #turns input to a datetime
                switch = 0
            except ValueError:
                week = input('Unrecognized date format, please try again: MM/DD/YYYY\n')
        beforeday = (input('Check days before date (Press enter to use today): MM/DD/YYYY\n')
            or dtt.date.today())
        if (beforeday != dtt.date.today()):
            switch = 1
            while switch == 1:
                try:
                    beforeday = dtt.datetime.strptime(beforeday,'%m/%d/%Y')
                    switch = 0
                except ValueError:
                    beforeday = input('Unrecognized date format, please try again: MM/DD/YYYY\n')
        return week, beforeday

Существуют также функции, которые проверяют индекс для данной даты и должны иметь дело с данной датой, не соответствующей ни одному из индексов:

def spotmap(week, bam, pt):
    """Maps the pivoted data for the chosen week to the BAM dataframe's SD column."""
    print('Mapping data to BAM... ',end=''),
    switch = 1
    while switch == 1:
        try:
            bam['SD'] = bam.index.to_series().map(pt.fillna(0)['len',week])
            switch = 0
        except KeyError:
            print('Invalid date, please try again.')
            week = input('Week start date (Sunday): MM/DD/YYYY\n')
    print('Done')
    return bam

Поскольку у скрипта есть много дел после того, как он получит эти даты, я не хочу, чтобы он зависал, когда у него возникла проблема, но он не может работать без правильных входных данных даты, поэтому в настоящее время он зацикливается с этими «переключателями». " переменные, контролирующие, когда он готов двигаться дальше с действительной датой. Однако, как вы можете видеть, эти блоки try/except быстро раздувают простой в остальном код. Есть ли способ сжать эти вещи? Кроме того, лучший метод, чем переключатели?

Повторяющиеся предложения Try и Except

В ответах здесь предлагались декораторы, но, насколько я могу судить из документации и таких страниц, как это, это для обертывания функций, а не для замены внутренних блоков кода. Также я не уверен, насколько они будут полезны, потому что блоки try/except в основном уникальны в том, что они пытаются выполнить (т. е. какую переменную они изменяют). Думаю, я действительно просто надеюсь на лучший синтаксис.


person Steve R    schedule 27.06.2017    source источник
comment
Я думаю, что Code Review может быть лучшим местом, где можно задать этот вопрос.   -  person Knowledge Cube    schedule 27.06.2017
comment
Ах хорошо. Тогда я сделаю это.   -  person Steve R    schedule 27.06.2017


Ответы (1)


Попробуйте завернуть повторяющиеся вызовы в функции, чтобы уменьшить раздувание. Вот удар по нему:

import numpy as np
import pandas as pd
import xlwings as xw
import datetime as dtt

def loop_until_good(func, arg):
    looping = True
    while looping:
        (arg, looping) = func(arg)
        return arg

def make_datetime(date):
    try:
        date = dtt.datetime.strptime(date,'%m/%d/%Y') #turns input to a datetime
        return date, False
    except ValueError:
        date = input('Unrecognized date format, please try again: MM/DD/YYYY\n')
        return date, True

def bammit(arg):
    (bam, week, pt) = arg
    try:
        bam['SD'] = bam.index.to_series().map(pt.fillna(0)['len',week])
        return (bam, week, pt), False
    except KeyError:
        print('Invalid date, please try again.')
        week = input('Week start date (Sunday): MM/DD/YYYY\n')
        return (bam, week, pt), True

def week_init():
        """Creates an initial week datetime and determines what the checking cutoff
        'beforeday' to be used in Stage 2 is."""
        week = str(input('Week to check: MM/DD/YYYY\n'))
        print type(week)
        print week
        loop_until_good(make_datetime, week)
        beforeday = (input('Check days before date (Press enter to use today): MM/DD/YYYY\n')
            or dtt.date.today())
        if (beforeday != dtt.date.today()):
            loop_until_good(make_datetime, beforeday)
        return week, beforeday

def spotmap(week, bam, pt):
    """Maps the pivoted data for the chosen week to the BAM dataframe's SD column."""
    print('Mapping data to BAM... ')
    loop_until_good(bammit, (bam, week, pt))
    print('Done')
    return bam
person mugwump    schedule 27.06.2017