跳至主要内容

不重要的布林值冷知識

高��見龍
五倍學院 負責人

在 Python 裡的布林型態(bool)的 TrueFalse,有些網路上的教學會說它們可以被轉型成數字 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 的內建型別是可以被繼承的,例如 intstrlist 或是 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 來代替布林值判斷,或是自己定義 TrueFalse,例如 True = 1 或是 False = 0 這樣的寫法。直到 PEP 285 提案之後才正式引入布林值的設計,並將上層類別設定成 int 類別。不過,即使 PEP 285 之後,在 Pytohn 2 時代 TrueFalse 還是可以被重新定義,像這樣:

# 注意,這是 Python 2
>>> True = False
>>> print(True)
False

直到 Python 3 之後,TrueFalse 才變成保留字,無法被重新定義。