טיפ פייתון: המרה לבוליאנים
הקוד הזה עובד יפה בפייתון:
import re
if re.search('a', 'hello'):
print("a found in hello")
else:
print("a not found in hello")
אבל זה לא כל כך:
if 'hello'.find('a'):
print("found a")
else:
print("a not found")
למרות שפייתון לא אוהב להמיר טיפוסים באופן אוטומטי, בכל הנוגע לבוליאנים הגישה של פייתון הפוכה, אלה הכללים:
אם יש פונקציית
__bool__
לדבר, פייתון יפעיל אותה כדי לגלות מה הערך הבוליאני.אם אין
__bool__
אבל יש__len__
, פייתון יפעיל את__len__
ויבדוק אם התוצאה אינה אפס.אם אין
__bool__
ואין__len__
מחזירים True.
הנה כמה ניסויים:
>>> None.__bool__()
False
>>> (-1).__bool__()
True
מה עם דוגמת הביטוי הרגולארי?
>>> re.search('a', 'hallo')
<re.Match object; span=(1, 2), match='a'>
>>> re.search('a', 'hallo').__bool__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 're.Match' object has no attribute '__bool__'. Did you mean: '__copy__'?
>>> re.search('a', 'hallo').__len__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 're.Match' object has no attribute '__len__'. Did you mean: '__le__'?
לביטוי רגולארי אין __bool__
ואין __len__
לכן הוא מחזיר True. והנה ניסוי עם קלאסים שלי:
class Foo:
def __bool__(self):
return False
class Bar:
pass
f = Foo()
if f:
print("Foo 1")
else:
print("Foo 2")
b = Bar()
if b:
print("Bar 1")
else:
print("Bar 2")
הפלט כצפוי Foo 2
ו Bar 1
.