不重要的布林值冷知識
在 Python 裡的布林型態(bool)的 True
跟 False
,有些網路上的教學會說它們可以被轉型成數字 1 跟 0。這樣的說法是沒問題,但可能比較少人知道在 Python 裡布林值其實就是一種數字。
布林值就是一種整數
不信的話,可以試著這樣做:
>>> bool.__base__
<class 'int'>
__base__
屬性可以取得類別的上層類別,所以可以看的出來 bool 的上層類別就是數字 int,它們之間是有繼承關係的,所以布林值就是一種(kind of)整數。
而且,在 Python 裡的 True 跟 False 都只存在一份,而且直接內建在 Python 直譯器裡,不管你怎麼建立新的布林物件,它們都會指向同一顆物件。例如:
>>> a = bool(123)
>>> b = bool("xyz")
>>> a is b
True
>>> a is True
True
可以看到它們就是同一顆物件。
另外,如果程式碼中使用了一看就知道的布林值判斷,例如:
if True:
print("這是真的")
因為這一定會發生,所以 Python 編譯的過程會直接把 if True
的判斷拿掉,只留下底下的程式碼:
0 0 RESUME 0
1 2 NOP
2 4 PUSH_NULL
6 LOAD_NAME 0 (print)
8 LOAD_CONST 1 ('這是真的')
10 CALL 1
18 POP_TOP
20 RETURN_CONST 2 (None)
反之,如果是這樣寫:
if False:
print("這根本不會發生")
因為這一定不會發生,所以這段程式碼直接會被 Python 無視,根本不會被編譯成 Bytecode:
0 0 RESUME 0
1 2 RETURN_CONST 1 (None)
布林類別不能被繼承
有些 Python 的內建型別是可以被繼承的,例如 int
、str
、list
或是 dict
等等,但是 bool
這個型別是不行的,如果試著繼承 bool 會得到錯誤訊息:
>>> class Cat(bool):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: type 'bool' is not an acceptable base type
其實本來只有 0 跟 1
最後再補個冷知識,在 Python 2.2 之前,Python 其實是沒有布林型態的,早期的開發者常會使用 0 和 1 來代替布林值判斷,或是自己定義 True
和 False
,例如 True = 1
或是 False = 0
這樣的寫法。直到 PEP 285 提案之後才正式引入布林值的設計,並將上層類別設定成 int
類別。不過,即使 PEP 285 之後,在 Pytohn 2 時代 True
跟 False
還是可以被重新定義,像這樣:
# 注意,這是 Python 2
>>> True = False
>>> print(True)
False
直到 Python 3 之後,True
跟 False
才變成保留字,無法被重新定義。