Python 布尔类型


在 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·
 

高效程序员

谈天 · 说地 · 侃代码 · 开车

长按识别二维码,解锁更多精彩内容

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值