Python 3中哪些条件失败了(如何检测哪些失败了)?

qq24tv8q  于 2023-08-08  发布在  Python
关注(0)|答案(2)|浏览(111)

下面是if

if condition_1 and condition2 and (condition3 or condition4):
   do something...

字符串
我想检测哪个条件失败了(什么条件是False),并将其写入日志以供进一步分析。如何在Python 3中做到这一点?

m3eecexj

m3eecexj1#

我已经找到了一个可能的解决方案,并与其他人分享:

conditions_dict = {"condition_name_1": [put your condition here, for example x < 5, the result should be True or False],
"condition_name_2": [put your condition here, for example x < 5, the result should be True or False], ...
}

    list_of_failed_conditions = [i for i in conditions_dict if not conditions_dict[i]]

    if len(list_of_failed_conditions) == 0:
        return True
    else:
        [log_function(err_msg) for err_msg in ["Condition failed: " + i for i in list_of_failed_conditions]]
        return False

字符串

e3bfsja2

e3bfsja22#

一种方法是使用类似决策表的东西:

decision_table = {
(0, 1): error_msg_1,
(1, 0): error_msg_2,
(0, 0): error_msg_1, #in case you want to give priority to one error message
}

字符串
然后,要根据失败的条件访问每条错误消息:

error_msg_for_logger = decision_table.get((condition_1, condition_2), "") #Return an empty string in case all conditions succeeded and there are no error messages
log_function(error_msg_for_logger)


因此,如果两个条件都成功(即(1, 1)场景),则不会显示错误消息。如果你想显示一个成功的消息,那么你可以在决策表中添加一个键(1, 1)和一个值successful_msg,这样你就可以得到类似的结果:(1, 1): successful_msg的值。
另一个更简单,在我看来更可读的方法是有一个函数来检查条件并根据哪个条件失败返回一个消息错误,类似于这样:

def validate_conditions(condition_1, condition_2):
        if not condition_1:
            error_msg = error_msg_for_condition_1
            return (False, error_msg) #Don't return if you want to have error messages for all of the failed conditions.
        elif not condition_2:#Change for an "if" if you want to have error messages for all of the failed conditions, otherwise, if you want to show only one, then use "elif".
            error_msg = error_msg_for_condition_2 #Or += "\n" + error_msg_for_condition_2 if you want to keep adding the error messages and show them in different lines.
            return (False, error_msg)
        return (True, None)


然后,在调用validate_conditions的代码中:

conditions_succeeded, error_msg = validate_conditions(condition_1, condition_2)
if not conditions_succeeded: #You could also just return the error_msg and not use a tuple at all, but I personally prefer it this way for readability purposes.
    log_function(error_msg)


当然,这只是一个例子,根据你的具体情况,你可以做的还有很多,例如,如果你有很多条件(如5、10或更多),你可以像上面的函数一样将它们拆分成几个函数,并将error_msg作为对象/列表的一部分传递。(因此,如果您想继续添加消息错误,而不是只显示一个,则保留对error_msg的更改),或者您也可以将所有条件包含在包含这些条件的对象中。例如,如果您正在检查用户是否有权访问应用程序的某个部分,您可以传递一个User对象,然后执行所有的验证,只传递这个User对象,而不是传递condition_1, condition_2, condition_3,等等。
此外,为了补充您的解决方案,如果您想向用户显示哪个条件没有成功(例如,用户在操作时处于非活动状态,或者用户没有足够的管理员权限等),conditions_dict中的键可以是要显示的错误消息。
或者,如果你想让条件名作为键,以便更容易阅读和理解,那么你可以使用一个元组作为值,其中第一个值是条件,第二个值是错误消息,所以在list_of_failed_conditions中,你可以使用i[1]而不是i,而不是if not conditions_dict[i][0]
此外,为了完成和提供更多的想法,您可以删除if/else块,并添加以下两行:

[log_function(err_msg) for err_msg in ["Condition failed: " + i for i in list_of_failed_conditions]]
return len(list_of_failed_conditions) == 0


这样,如果没有要记录的消息,log_function行将不会运行(也不会抛出任何异常),如果list_of_failed_conditions的len为0,函数将返回True,如果不是,则返回False,所以行为仍然相同。对于一些人来说,这可能有点难以阅读,但我至少觉得它更简单(如果你想更进一步,你可以只返回not len(list_of_failed_conditions),而不将其与0进行比较,因为在Python中整数值具有相关的布尔值,所以0被视为False,任何其他数字都被视为True,但在这一点上,我认为这是走得太远了)。
这一切都取决于你的具体情况,但我仍然想在这里张贴不同的选项,以便它可以帮助更多的人在不同的情况。

相关问题