在 Python 中,用于存储真值和假值的类型称为 bool
,以英国数学家 George Boole(乔治·布尔)的名字命名。George Boole 创建了布尔代数,它是所有现代计算机算术的基础。
布尔值只有两个,分别是 True 和 False。
一定要注意大小写,因为 true 和 false 并不是布尔值(记住,Python 是区分大小写的)。
1
深入理解
为了深入理解 bool 类型,我们先来查看帮助文档:
>>> help(bool)
Help on class bool in module builtins:
class bool(int)
| bool(x) -> bool
|
| Returns True when the argument x is true, False otherwise.
| The builtins True and False are the only two instances of the class bool.
| The class bool is a subclass of the class int, and cannot be subclassed.
|
| Method resolution order:
| bool
| int
| object
|
| Methods defined here:
|
| __and__(self, value, /)
| Return self&value.
|
| __or__(self, value, /)
| Return self|value.
可以看到,bool 是 int 的子类,仅有 True 和 False 两个实例,而且它不能被子类化:
>>> type(True)
<class 'bool'>
>>> type(False) # True 和 False 都是 bool 类型
<class 'bool'>
>>>
>>> issubclass(bool, int) # bool 是 int 的子类
True
>>>
>>> class SubBool(bool): # bool 不能被子类化
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type 'bool' is not an acceptable base type
由于是 int 的子类,因此 bool 类型也可以进行基本运算:
>>> True + 1
2
>>> False * 10
0
>>> True + False
1
>>> True * False
0
你会发现,True 对应的整数值是 1,而 False 则对应 0:
>>> True == 1
True
>>> False == 0
True
>>> True == 0
False
>>> False == 1
False
用一句话总结 True 和 False:它们是整数 1 和 0 的替代写法,
唯一区别是 str() 和 repr() 会返回字符串“True”和“False”,而不是“1”和“0”:
>>> str(True)
'True'
>>> repr(False)
'False'
2
真假值测试
每个对象都有一个布尔值,以下元素会被认定为 False:
- None
- False
- 任何数字类型的 0,例如:0、0.0、0j。
- 任何空序列,例如:''、()、[]
- 任何空映射,例如:{}
- 自定义的类实例,该类定义了 __bool__() 或 __len__() 方法,并返回 False 或者 0。
注意:除以上情况外,其它表达式均会被认定为 True。
>>> print(bool())
False
>>>
>>> print(bool(False))
False
>>>
>>> print(bool(0), bool(0.0), bool(0j))
False False False
>>>
>>> print(bool(''), bool(()), bool([]), bool({}))
False False False False
>>>
>>> class A():
... def __len__(self): # 定义了 __len__() 方法,始终返回 0
... return 0
...
>>> class B():
... def __bool__(self): # 定义了 __bool__() 方法,始终返回 False
... return False
...
>>> class C(): # 一般的类
... pass
...
>>> a = A()
>>> bool(a)
False
>>>
>>> b = B()
>>> bool(b)
False
>>>
>>> c = C()
>>> bool(c) # 一般对象,都返回 True
True
回过头来,我们再分析一下:
>>> True == 1
True
>>> True == 2
False
很显然,True 不能既等于 1,又等于 2。如果同时成立的话,1 岂不是要等于 2,这分明是不可接受的!
现在,我们再来看:
>>> if 2:
... print("bool")
...
bool
但在这里,语句为什么又被打印出来了呢?
这是因为 if 内部会调用 bool() 方法,而我们上面说过:任何数字类型的 0 都是 False,那么 bool(2) 则一定是 True:
>>> bool(2)
True
这就是为什么打印语句会被执行的原因,因此一定要区分这两种情况,它们是不同的!
3
常见用法
在 Python 运算符 一节中,我们分享了各种各样的运算符,其中很多运算符都可用于测试真假值。
这里列举一些简单的例子:
>>> x = True
>>> y = False
>>> x and y # 逻辑(布尔)运算符
False
>>> x or y
True
>>> not x
False
>>>
>>> 5 <= 2 # 比较运算符
False
>>>
>>> ceo = teacher = 'Jack Ma' # 身份运算符
>>> ceo is teacher
True
>>>
>>> 'a' in 'Happy' # 成员运算符
True
此外,还可以将比较运算符连起来(链式比较
):
>>> x = 2
>>> 0 < x < 5
True
>>>
>>> 5 < x < 10
False
在这种情况下,会对每个术语进行比较。
例如,在第一个语句中,会先比较 0 < x,再比较 x < 5(并不是将 0 < x 的结果 True 和后面的进行比较:True < 5)。
4
重要细节
短路运算
为了加速布尔值的计算,Python 使用了短路运算。
这意味着,当有多个表达式时,一旦左边的表达式值可以确定结果,就不再继续计算右边表达式的值。
例如,对于下面的表达式来说:
>>> True or x # 总是 True
True
>>>
>>> False and x # 总是 False
False
无论 x 的值是什么,第一个表达式的值永远是 True,而第二个表达式永远是 False,所以没有继续向后计算的必要(在第一个表达式中,永远不会计算 or x;相应地,在第二个表达式中,也永远不会计算 and x)。
要验证是否是短路运算,可以使用一些特殊的手段,例如:
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
>>> True or 1/0 # 并不会计算 1/0
True
可以看到,除数不能为 0,一旦为 0,程序就会出现异常。
但在第二个表达式中,并没有任何异常产生,这正是因为发生了短路运算(不会去计算 1/0)。
返回值
在逻辑运算中,返回值是最后计算的值。
考虑以下示例:
>>> print(True and 'Yes' or 'No')
Yes
>>>
>>> print(False and 'Yes' or 'No')
No
在第一个语句中,True and 'Yes' 为 True,所以不需要计算 or 'No'。因此在运算结束之后,返回的值是在 True and 'Yes' 中最后被计算的值,即:'Yes'。
在第二个语句中,False and 'Yes' 为 False,所以必须计算 or 'No'。而最后计算的是 'No',因此它就是返回值。
优先级
再来说说优先级:
>>> True and False or True
True
由于 and 的优先级更高,所以首先计算“True and False”,其结果是 False。因此,接下来的计算变成了“False or True”,结果是 True。
为了确保你写的正是你想表达的意思,有时候用括号可能会更加直观:
>>> (True and False) or True
True
·END·
高效程序员
谈天 · 说地 · 侃代码 · 开车
长按识别二维码,解锁更多精彩内容