据我所见,None
和False
的唯一不同之处是将它们相互比较(以确保相等)。我是否缺少某些东西,或者只要您一致使用,可以只使用其中一种吗?有什么理由要使用另一个?
答案 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
,然后一切都会正常进行。每当您将变量传递给if
,while
,任何布尔运算符(例如or
,and
等)或任何内置函数时,Python都会自动将其转换为布尔值期望为布尔值(旁注:尽管or
和and
确实在确定返回值的同时将您的值转换为布尔值,但最终结果将是您未转换的值)。这就是为什么很难说出区别。
但是,大多数开发人员会认为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