将多个try / except块转换为函数

时间:2018-05-31 00:29:58

标签: python function try-catch

这是一个与实际代码相关的一般编程问题。

我有这个丑陋的代码,它接受来自JIRA的输入并将其从毫秒转换为多次写出的小时,如下所示:

def convertMillis(ms):
    hours = ms / 1000 / 60 / 60
    return hours

try:
    newaccsla_comp = convertMillis(issues.fields.customfield_10705.completedCycles[0].remainingTime.millis)
except:
    newaccsla_comp = np.nan
try:
    newaccsla_ongoing = convertMillis(issues.fields.customfield_10705.ongoingCycle.remainingTime.millis)
except:
    newaccsla_ongoing = np.nan

try:
    paymentssla_comp = convertMillis(issues.fields.customfield_10136.completedCycles[0].remainingTime.millis)
except:
    paymentssla_comp = np.nan
try:
    paymentssla_ongoing = convertMillis(issues.fields.customfield_10136.ongoingCycle.remainingTime.millis)
except:
    paymentssla_ongoing = np.nan

try:
    modifysla_comp = convertMillis(issues.fields.customfield_10713.completedCycles[0].remainingTime.millis)
except:
    modifysla_comp = np.nan
try:
    modifysla_ongoing = convertMillis(issues.fields.customfield_10713.ongoingCycle.remainingTime.millis)
except:
    modifysla_ongoing = np.nan

try:
    MFsla_comp = convertMillis(issues.fields.customfield_10711.completedCycles[0].remainingTime.millis)
except:
    MFsla_comp = np.nan
try:
    MFsla_ongoing = convertMillis(issues.fields.customfield_10711.ongoingCycle.remainingTime.millis)
except:
    MFsla_ongoing = np.nan

try:
    closeaccsla_comp = convertMillis(issues.fields.customfield_10140.completedCycles[0].remainingTime.millis)
except:
    closeaccsla_comp = np.nan
try:
    closeaccsla_ongoing = convertMillis(issues.fields.customfield_10140.ongoingCycle.remainingTime.millis)
except:
    closeaccsla_ongoing = np.nan

try:
    casla_comp = convertMillis(issues.fields.customfield_10213.completedCycles[0].remainingTime.millis)
except:
    casla_comp = np.nan
try:
    casla_ongoing = convertMillis(issues.fields.customfield_10213.ongoingCycle.remainingTime.millis)
except:
    casla_ongoing = np.nan

try:
    at_comp = convertMillis(issues.fields.customfield_10144.completedCycles[0].remainingTime.millis)
except:
    at_comp = np.nan
try:
    at_ongoing = convertMillis(issues.fields.customfield_10144.ongoingCycle.remainingTime.millis)
except:
    at_ongoing = np.nan

try:
    modfeesla_comp = convertMillis(issues.fields.customfield_10134.completedCycles[0].remainingTime.millis)
except:
    modfeesla_comp = np.nan
try:
    modfeesla_ongoing = convertMillis(issues.fields.customfield_10134.ongoingCycle.remainingTime.millis)
except:
    modfeesla_ongoing = np.nan

try:
    tdsla_comp = convertMillis(issues.fields.customfield_11200.completedCycles[0].remainingTime.millis)
except:
    tdsla_comp = np.nan
try:
    tdsla_ongoing = convertMillis(issues.fields.customfield_11200.ongoingCycle.remainingTime.millis)
except:
    tdsla_ongoing = np.nan

try:
    querysla_comp = convertMillis(issues.fields.customfield_10142.completedCycles[0].remainingTime.millis)
except:
    querysla_comp = np.nan
try:
    querysla_ongoing = convertMillis(issues.fields.customfield_10142.ongoingCycle.remainingTime.millis)
except:
    querysla_ongoing = np.nan

try:
    recsla_comp = convertMillis(issues.fields.customfield_15600.completedCycles[0].remainingTime.millis)
except:
    recsla_comp = np.nan
try:
    recsla_ongoing = convertMillis(issues.fields.customfield_15600.ongoingCycle.remainingTime.millis)
except:
    recsla_ongoing = np.nan

try:
    reportsla_comp = convertMillis(issues.fields.customfield_15601.completedCycles[0].remainingTime.millis)
except:
    reportsla_comp = np.nan
try:
    reportsla_ongoing = convertMillis(issues.fields.customfield_15601.ongoingCycle.remainingTime.millis)
except:
    reportsla_ongoing = np.nan

我很乐意做一些事情,比如取所有自定义字段,将它们放在一个列表中,然后对这个函数执行for:

field_list = ['customfield_10705','customfield_10136','customfield_10713','customfield_10711','customfield_10140','customfield_10213','customfield_10144','customfield_10134','customfield_11200','customfield_10142','customfield_15600','customfield_15601']


  def get_jira_hours(field):
        try:
            newaccsla_comp = convertMillis(issues.fields.field.completedCycles[0].remainingTime.millis)
        except:
            newaccsla_comp = np.nan
        try:
            newaccsla_ongoing = convertMillis(issues.fields.field.ongoingCycle.remainingTime.millis)
        except:
            newaccsla_ongoing = np.nan

for field in field_list:
    get_jira_hours(field)

但是,有三个变量链接到我需要迭代的每个函数调用 - customfield_10705和保存每个try /的名称/ newaccsla_compnewaccsla_ongoing除外。

这里是变量的顺序..即。 field_list[0]name_list[0]

相关联
field_list = ['customfield_10705','customfield_10136','customfield_10713','customfield_10711','customfield_10140','customfield_10213','customfield_10144','customfield_10134','customfield_11200','customfield_10142','customfield_15600','customfield_15601']

name_list = ['newaccsla','paymentssla','modifysla','MFsla','closeaccsla','casla','at','modfeesla','tdsla','querysla','recsla','reportssla']

迭代这些的最好方法是什么?感谢。

1 个答案:

答案 0 :(得分:4)

首先,如果您只是编辑convertMillis函数以返回np.nan而不是提升 - 或者,如果您不能这样做,则可以将每个四行块转换为单行那个,将函数包装在另一个函数中:

def convertMillisOrNan(millis):
    try:
        return convertMillis(millis)
    except:
        return np.nan

newaccsla_comp = convertMillisOrNan(issues.fields.customfield_10705.completedCycles[0].remainingTime.millis)
newaccsla_ongoing = convertMillisOrNan(issues.fields.customfield_10705.ongoingCycle.remainingTime.millis)
# etc.

或者,也许您尝试处理的例外情况会更进一步。您始终在convertMillis上致电<something>.remainingTime.millis。如果该字段始终存在,并且始终具有ongoingCycle,但并不总是具有remainingTime属性,该怎么办?然后,您可以将该部分推送到try:,同时还可以进一步简化:

def convertCycle(cycle):
    try:
        return convertMillis(cycle.remainingTime.millis)
    except:
        return np.nan
newaccsla_comp = convertCycle(issues.fields.customfield_10705.completedCycles[0])
newaccsla_ongoing = convertCycle(issues.fields.customfield_10705.ongoingCycle)

如果异常更高 - 例如,如果字段并不总是ongoingCycle - 显然你需要在try:块内推送更多的表达式;我真的只是在猜测你要用except:处理的内容。

而且,当你在这里时,你真的想要一个裸except:吗?这将处理任何异常,而不仅仅是AttributeErrorValueError或您实际期望的任何异常。

与此同时,您现有的jira_hours重构不起作用,因为当.field是一个包含字符串的变量时,您不能只使用field。解决这个问题的一种方法是:

def get_jira_hours(field):
    comp = convertCycle(field.completedCycles[0])
    ongoing = convertCycle(field.ongoingCycle)
    return comp, ongoing

newaccsla_comp, newaccsla_ongoing = get_jira_hours(issues.fields.customfield_10705)
paymentssla_comp, paymentssla_ongoing = get_jira_hours(issues.fields.customfield_10136)
# etc.

解决问题的另一种方法是使用getattr - 我将在下面显示。

但你可以做得更好。你真的需要这些都是独立的变量,而不是说dict中的项目吗?

fieldmap = {
    'newaccsla': 'customfield_10136',
    'paymentssla': 'customfield_10705',
    # etc.
}

values = {}
for fieldname, customfieldname in fieldmap.items():
    field = getattr(issues.fields, customfieldname)
    comp, ongoing = get_jira_hours(field)
    values[f'{fieldname}_comp'] = comp
    values[f'{fieldname}_ongoing'] = ongoing

现在,您必须使用newaccsla_comp,而不是使用values['newaccsla_comp']。但是我怀疑你的代码实际上会执行很多代码,你可以为每个变量复制和粘贴相同的东西,你可以用直接遍及dict的代码替换它。

但是如果你确实需要将这些作为独立变量 - 你可能再做一次 - 只需使用globals()locals()而不是values就可以做同样的事情。

另一方面,如果你要重复comp /正在进行的值对,只需将对存储在dict中:values[fieldname] = comp, ongoing

此外,由于所有自定义字段名称似乎都是customfield_NNNNN,因此您可以通过映射'newaccsla': 10136等,然后执行getattr(issue.fields, f'customfield_{customfield}')来进一步简化操作。