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

Python 将多个try/except块转换为函数,python,function,try-catch,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.m

这是一个更一般的编程问题,而不是与实际代码相关的问题

我有一段难看的代码,它从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
我会很乐意做一些事情,比如获取所有自定义字段,将它们放在一个列表中,然后对函数执行如下操作:

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/except的名称
newaccsla\u comp
newaccsla\u continuous

下面是按顺序排列的变量。。例如,
字段列表[0]
链接到
名称列表[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']

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

首先,如果您只需编辑
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.

或者,你试图处理的异常可能会更进一步。您总是在
.remainingTime.millis
上调用
convertMillis
。如果该字段始终存在,并且始终具有
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:
块中推送更多表达式;我真的只是在这里猜测一下,除了:,你想用它来处理什么


而且,当你这么做的时候,除了:,你真的想要一个空的
?这将处理任何异常,而不仅仅是
AttributeError
ValueError
或您实际期望的任何类型的异常


同时,现有的
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']
,而不是使用
newaccsla_comp
。但是我怀疑你的代码实际上会做很多代码,你会为每个变量复制和粘贴相同的东西,你可以用在dict上循环的代码来替换

但是,如果你真的需要这些变量作为自变量,那么你也可以通过使用
globals()
locals()
而不是
值来做同样的事情

另一方面,如果您要在comp/正在进行的值对上重复自己的操作,只需将这些值对存储在dict:
values[fieldname]=comp,consuming
中即可


此外,由于所有自定义字段名称似乎都是
customfield\unnnnn
,您可以通过映射
'newaccsla':10136
等,然后先执行
getattr(issue.fields,f'customfield{customfield}')
来进一步简化,如果您只需编辑
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.

或者,你试图处理的异常可能会更进一步。您总是在
.remainingTime.millis
上调用
convertMillis
。如果该字段始终存在,并且始终具有
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:
块中推送更多表达式;我真的只是在这里猜测一下,除了:
,你想用它来处理什么


而且,当你这么做的时候,除了:
,你真的想要一个空的
?这将处理任何异常,而不仅仅是
AttributeError
ValueError
或您实际期望的任何类型的异常


同时,现有的
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']
,而不是使用
newaccsla_comp
。但是我怀疑你的代码实际上会做很多代码,你会为每个变量复制和粘贴相同的东西,你可以用在dict上循环的代码来替换

但是,如果你真的需要这些变量作为自变量,那么你也可以通过使用
globals()
locals()
而不是
值来做同样的事情

另一方面,如果您要在comp/正在进行的值对上重复自己的操作,只需将这些值对存储在dict:
values[fieldname]=comp,consuming
中即可

此外,由于所有自定义字段名称似乎都是
customfield\unnnnn
,因此可以通过映射
“newaccsla”:1013进一步简化