【问题标题】:'Force' Python to evaluate all boolean expressions [duplicate]“强制”Python评估所有布尔表达式[重复]
【发布时间】:2019-03-12 02:33:35
【问题描述】:

大多数语言都有办法通过强制 if 中的所有布尔值都被评估来强制“尽早且经常失败”。

假设我在 Python 中有以下 if 语句:

if(age>100 or patient_is_brain_dead or patient_lacks_left_arm):
    do something...

问题是我可能忘记为“patient_is_brain_dead”或“has_no_left_arm”设置布尔值。

由于大多数活着的人都在 100 岁以下,因此测试 2 和 3 很少发生,因为 Python 看到前面的“或”会停止评估年龄是否小于 100 以节省时间。

我的代码受大量计算限制,因此测试所有三种情况的开销不会降低性能,但会发现很多潜在的错误,这些错误可能会在 500 分之一的情况下发生。

有没有办法强制 Python 对它们全部进行评估?不要建议颠倒顺序,因为任何情况都可能是罕见的,具体取决于用户输入。

【问题讨论】:

  • 我认为unit tests在这里可能有用。
  • ...或者通过明确检查patient_is_brain_dead is not None and patient_lacks_left_arm is not None,又名“忘记设置”,然后引发异常?
  • 我认为这可行,但这是一种相当迂回的方法。我认为把它放在括号里就可以了,但可惜不是。
  • 脑死亡和左臂检查通常发生在您写的那一行,因为如果左侧为假,or 必须继续进行。跨度>
  • @eSurfsnake,这是错字吗?根据您的描述,您似乎想要逻辑if age < 100 or ... or ...

标签: python python-3.x boolean-expression


【解决方案1】:

在我看来,您不应该想要在生产代码中这样做。如果有几个变量应该是布尔值并且您需要检查它们是否是True,您应该使用短路逻辑。

如您所说,如果您想确保您的代码不会在边缘情况下失败,那么您有哪些选择?您可以使用unit testing 来测试所有可行的方案。但这对您的用例来说可能有点过分了。您可以只使用assert 声明:

assert all(isinstance(i, bool) for i in [patient_is_brain_dead, patient_lacks_left_arm])

if age > 100 or patient_is_brain_dead or patient_lacks_left_arm:
    # do something...

这种解决方案的好处是可以通过命令行-O 对生产代码使用turn off assert 语句。同时,出于测试目的,您可以确保变量的类型正确。

【讨论】:

  • 我来自 C 系统编程环境。对于计算密集型代码,如果接下来要做的是将两个 100 x 100 矩阵相乘或具有数千个点的大卷积,那么进行三项检查是微不足道的。最好清除用户(和程序员)错误,因为 99.999% 的执行时间不在冗余检查中。
  • 是的,所以 assert 会为你做这件事。我想说这也是一种 Pythonic 方法。
【解决方案2】:

不,您需要明确检查None。这不是一种“迂回”的方式,这正是语言的工作方式。

如果您希望条件在未设置任何变量的情况下失败,您可以使用all() 来检查它们是否不是None

if(all(i is not None for i in [age, patient_is_brain_dead, patient_lacks_left_arm]) and
        (age > 100 or patient_is_brain_dead or patient_lacks_left_arm)):
    do something...

【讨论】:

  • 那肯定很丑……
  • 我可能对任何 C 代码都这么说,但我们都有自己的偏好:P
  • au,相反。 C 代码通常比这更好看...
猜你喜欢
  • 2018-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-08
相关资源
最近更新 更多