我什么时候应该使用 None vs False?

When should I use None vs False?

据我所知,NoneFalse 唯一一次表现不同是在将它们相互比较时(为了相等)。我是否遗漏了什么,或者只要您的用法一致,就可以只使用一个或另一个吗?有什么理由要用一个而不是另一个吗?

我会在这里强调语义上的差异而不是行为上的差异。

让我们考虑几个函数:

def find_user(criteria):
    if is_met(criteria):
        return User(...)
    return None

# ...vs 

def has_email(user):
    return bool(user.email)

对我来说,None 背后的语义意味着没有价值,而 False 背后的语义意味着布尔值错误。

这里的类比可以是 C++ 中 bool 类型的演进。当 C (ab) 将 int 用于布尔逻辑时,C++ 引入了一种专用的 bool 类型,这使得某些 variables/function 签名背后的意图更加清晰。它还允许进行一些优化,例如 std::vector<bool> 在内部表示为位向量而不是字节。

如果要检查值是否已分配或存在,可以使用 None

dct = {'key':'value'}
x = dct.get('key', None) # Get the value or get`None if it doesn't exist

def func(...):
   if condition:
      return Object()
   return None

而如果您知道该值将存在但想检查它是 属性,请使用 False

if empty_list: #An empty list evaluates to `False`
   do something
if not bool_var:
   do something

另外 bool(None) 的计算结果为 False

它们是不同的类型。尽管在实践中,它们的行为非常相似。您还可以将 False 替换为:""[](,)0,一切都会正常进行。每当您将变量传递给 ifwhile 或任何布尔运算符(例如 orand 等)时,Python 会自动将您的变量转换为布尔值或任何需要布尔值的内置函数(旁注:尽管 orand 确实将您的值转换为布尔值,同时决定将什么转换为 return,最终结果将是您未转换的值)。这就是为什么很难区分的原因。

然而,大多数开发者会认为 None 类似于其他语言中的 null 值,这是一个错误或未初始化的值。 Whilist False 通常被认为是一个预期的和完全初始化的值。因此,如果您坚持该约定,大多数人将更容易阅读您的代码。

进一步阐述这一点,让我们考虑 C Python 实现。典型的 if 语句将转换为 POP_JUMP_IF_FALSE(或 POP_JUMP_IF_TRUE)指令。这是如何实现的:

TARGET(POP_JUMP_IF_FALSE) {
    PyObject *cond = POP();
    int err;
    if (cond == Py_True) {
        Py_DECREF(cond);
        FAST_DISPATCH();
    }
    if (cond == Py_False) {
        Py_DECREF(cond);
        JUMPTO(oparg);
        FAST_DISPATCH();
    }
    err = PyObject_IsTrue(cond);
    Py_DECREF(cond);
    if (err > 0)
        ;
    else if (err == 0)
        JUMPTO(oparg);
    else
        goto error;
    DISPATCH();
}

如您所见,如果传递给 if 的值是一个布尔值,解释器将立即知道该怎么做。否则,它将调用 PyObject_IsTrue,这将尝试使用任何可能的方式将对象转换为布尔值(__bool____nonzero____len__,甚至与 None 明确)。