如何在不不断重复代码的情况下捕获异常并为变量分配特定值?

How can I make catching exceptions assign a variable a certain value without constantly repeating the code?

我要澄清一下。

我正在记录 6 个不同的变量,其中一些有错误(什么样的错误并不重要)。发生该错误时,我只想将该特定变量放入“NA”。

以下是我的意思:

myDict = []
for i in data:
    try:
        eye = ...
        nose = ...
        mouth = ...
        ear = ...
        hair = ...
        tongue = ...
        
        myDict.append([eye, nose, mouth, ear, hair, tongue])

   except eye:
        eye = "NA"
        myDict.append([eye, nose, mouth, ear, hair, tongue])
  
   except nose:
        nose = "NA"
        myDict.append([eye, nose, mouth, ear, hair, tongue])

   except mouth:
        mouth = "NA"
        myDict.append([eye, nose, mouth, ear, hair, tongue])

   ...

我是否必须为每个变量做一个“例外”?有什么方法可以让我做到“除非变量有错误,将其值赋给“NA”并正常追加”?

我也不知道如果超过 1 个变量出现错误会怎样。

基本思想是:“如果变量 (S) 有错误,只需分配 it/them 值“NA”并继续追加。

这是一个可以满足您要求的方法的示例。

先评论一下:

  • 您使用了术语“错误”,但您的示例代码使用了 try/except,因此我假设每个“错误”都会引发异常。
  • 在下面的代码中,我使用了一个人为简化的场景,其中对每个变量的赋值都有可能引发具有相似名称的异常,并且我将这些创建为 user-defined 异常;实际上,您可能不需要定义这些,而是​​将示例代码中带括号的异常类型替换为您想要捕获的实际异常。
  • 你有一个叫做 myDict 的东西,它实际上是一个 python 列表;我将在下面的代码中重命名此 result 以避免混淆。

下面代码的逻辑可以概括为:

  • 与其直接分配给命名变量(如您问题中的代码),不如在内部循环中遍历变量标签列表(字符串如 'eye'、'nose' 等)里面有一个 try/except 块的循环;
  • 在此内部列表中,对给定标签执行操作(与您问题中的 eye = ...mouth = ... 执行的操作相同)并将结果附加到列表 L,除非引发异常,在这种情况下,try 块将“NA”附加到 L
  • 这意味着无论是否有错误(更准确地说,是否引发异常),L都会为每个变量标签附加一个值;
  • 在内循环结束时,将 L 附加到结果。

示例代码如下:

class eye_exception(Exception):
    pass
class nose_exception(Exception):
    pass
class mouth_exception(Exception):
    pass
class ear_exception(Exception):
    pass
class hair_exception(Exception):
    pass
class tongue_exception(Exception):
    pass


def getValueForEye(i):
    return "eye_value" + str(i)
def getValueForNose(i):
    return "nose_value" + str(i)
def getValueForMouth(i):
    if i % 3 == 0:
        raise mouth_exception()
    return "mouth_value" + str(i)
def getValueForEar(i):
    return "ear_value" + str(i)
def getValueForHair(i):
    if i % 3 != 0:
        raise hair_exception()
    return "hair_value" + str(i)
def getValueForTongue(i):
    return "tongue_value" + str(i)

data = [1, 2, 3]

result = []
for i in data:
    L = []
    for key in ['eye', 'nose', 'mouth', 'ear', 'hair', 'tongue']: 
        try:
            match key:
                case 'eye':
                     value = getValueForEye(i)
                case 'nose':
                     value = getValueForNose(i)
                case 'mouth':
                     value = getValueForMouth(i)
                case 'ear':
                     value = getValueForEar(i)
                case 'hair':
                     value = getValueForHair(i)
                case 'tongue':
                     value = getValueForTongue(i)
            L.append(value)
        except (eye_exception, nose_exception, mouth_exception, ear_exception, hair_exception, tongue_exception):
            L.append("NA")
    result.append(L)

样本result:

['eye_value1', 'nose_value1', 'mouth_value1', 'ear_value1', 'NA', 'tongue_value1']
['eye_value2', 'nose_value2', 'mouth_value2', 'ear_value2', 'NA', 'tongue_value2']
['eye_value3', 'nose_value3', 'NA', 'ear_value3', 'hair_value3', 'tongue_value3']

或者,如果您使用的 python 版本不支持 match/case 构造,或者您只是不想使用它,则可以用以下代码替换上面的循环使用字典从变量标签映射到函数:

funcDict = {
    'eye':getValueForEye, 
    'nose':getValueForNose, 
    'mouth':getValueForMouth, 
    'ear':getValueForEar, 
    'hair':getValueForHair, 
    'tongue':getValueForTongue
}
for i in data:
    L = []
    for key, func in funcDict.items(): 
        try:
            value = func(i)
            L.append(value)
        except (eye_exception, nose_exception, mouth_exception, ear_exception, hair_exception, tongue_exception):
            L.append("NA")
    result.append(L)