在 python 中压缩重复的 try-except 语句
Condensing repetitive try-except statements in 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
由于脚本在获得这些日期后有很多事情要做,我不希望它在出现问题时崩溃,但如果没有正确的日期输入它就无法继续,所以我目前有它循环使用那些 "switch" 变量来控制它何时愿意继续使用有效日期。但是,如您所见,这些 try/except 块正在迅速膨胀本来简单的代码。有没有办法把这些东西浓缩出来?另外,有比开关更好的方法吗?
Repetitive Try and Except Clauses
这里的答案建议装饰器,但据我从文档和 this 之类的页面可以看出,这些是用于包装函数,而不是用于替换内部代码块。此外,我不确定它们会有多大用处,因为 try/except 块在它们试图完成的任务(即它们正在更改的变量)方面大多是独一无二的。我想我真的只是希望有一些更好的语法。
尝试在函数中结束重复调用以减少膨胀。这是一个尝试:
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
我有一个脚本要求用户输入很多日期,主要是在类似于下面的函数中。这些需要考虑无效的日期格式:
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
由于脚本在获得这些日期后有很多事情要做,我不希望它在出现问题时崩溃,但如果没有正确的日期输入它就无法继续,所以我目前有它循环使用那些 "switch" 变量来控制它何时愿意继续使用有效日期。但是,如您所见,这些 try/except 块正在迅速膨胀本来简单的代码。有没有办法把这些东西浓缩出来?另外,有比开关更好的方法吗?
Repetitive Try and Except Clauses
这里的答案建议装饰器,但据我从文档和 this 之类的页面可以看出,这些是用于包装函数,而不是用于替换内部代码块。此外,我不确定它们会有多大用处,因为 try/except 块在它们试图完成的任务(即它们正在更改的变量)方面大多是独一无二的。我想我真的只是希望有一些更好的语法。
尝试在函数中结束重复调用以减少膨胀。这是一个尝试:
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