什么时候应该使用None和False?

时间:2019-03-23 11:36:57

标签: python boolean nonetype

据我所见,NoneFalse的唯一不同之处是将它们相互比较(以确保相等)。我是否缺少某些东西,或者只要您一致使用,可以只使用其中一种吗?有什么理由要使用另一个?

3 个答案:

答案 0 :(得分:5)

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

让我们考虑几个功能:

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类型,该类型使某些变量/函数签名的意图更加清晰。并且还允许进行一些优化,例如std::vector<bool>在内部表示为位的向量,而不是字节的向量。

答案 1 :(得分:1)

它们是不同的类型。尽管实际上它们的行为非常相似。您也可以将False替换为""[](,)0,然后一切都会正常进行。每当您将变量传递给ifwhile,任何布尔运算符(例如orand等)或任何内置函数时,Python都会自动将其转换为布尔值期望为布尔值(旁注:尽管orand确实在确定返回值的同时将您的值转换为布尔值,但最终结果将是您未转换的值)。这就是为什么很难说出区别。

但是,大多数开发人员会认为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进行比较,将对象转换为bool。 )。

答案 2 :(得分:0)

如果要检查值是否已分配或存在,可以使用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