Python的秘密生活:关于虚无的真相
Source: Dev.to
图书馆很安静,只有蒂莫西笔尖有节奏的划动声。他正在屏幕上调试一个函数,并把它与笔记交叉对照。
“Margaret,”他说,抬起头。“我觉得我已经掌握了这种可读性的要领。看看我把这些检查写得多么明确。”
他把笔记本电脑转了过去。
# Timothy's "Explicit" Code
def process_order(items, user_name):
if len(items) > 0:
print("Processing items...")
if user_name != "":
print(f"User is: {user_name}")
if items is not None:
# do something else
“这非常……彻底,”蒂莫西笑着说。“我检查所有东西。我检查列表长度是否大于零。我检查字符串是否非空。我不留下任何偶然。”
玛格丽特戴着眼镜俯视着说。“的确很彻底,蒂莫西。但这相当于用浓重的口音在说 Python。”
她伸手去敲键盘。“在 Python 中,我们不会用二十个问题审问对象。我们只需让它们自行给出答案。”
真理的“尺度”
Margaret 删除了 Timothy 那冗长的检查,并用下面的代码替代了它:
# Margaret's "Pythonic" Code
def process_order(items, user_name):
if items:
print("Processing items...")
if user_name:
print(f"User is: {user_name}")
Timothy 皱起眉头。“等等。if items:?但是 items 是一个列表,而不是布尔值。它既不是 True 也不是 False。它是一个集合。”
“在 Python 中,每个对象都有 Truthiness(真值性)。这不仅仅是布尔值
True或False,而是关于 实质 的。”
她在天平的一侧放了一本厚书。天平倾斜了。
“这个列表里有元素。它有重量。因此,它是 Truthy(真值)。”
她把书移走,天平空荡且保持平衡。
“这个列表是空的。它没有重量。因此,它是 Falsy(假值)。”
“空白”陷阱
Timothy 缓缓点头。“好。如果它有内容,就是 True;如果是空的,就是 False。”
他再次查看自己的代码。“所以如果用户在名字里只输入一个空格——只按一下空格键——那算是空的,对吧?那 if user_name: 应该是 False 吗?”
“要小心,” Margaret 警告道。“空气有重量吗?”
“从技术上讲…有。”
“一串只包含空格的字符串并不为空,” Margaret 纠正道。“它包含一个字符:空格字符。因此,它是有‘重量’的。”
她快速演示了一段代码:
name = " " # 只包含一个空格
if name:
print("This name is Truthy!")
else:
print("This name is Falsy!")
输出
This name is Truthy!
Timothy 看起来很惊讶。“这可能是个 bug。如果我想阻止用户使用空白名字,这个检查会让他们通过。”
“正是如此,” Margaret 说。“这正是少数几次必须明确的情况。如果你想检查‘实质内容’,而不仅仅是空白字符,需要先去除空格:
if name.strip():。”
真值审计
“这变得越来越棘手,” Timothy 说。“我怎么才能确定什么算作‘空’?”
“我们对它们进行审计,” Margaret 回答。“我们把它们放到天平上。”
她写了一个脚本,循环遍历常见的“空”值并检查它们的官方布尔状态:
# The Truthiness Audit
suspects = [
[], # Empty List
[1], # List with item
"", # Empty String
" ", # String with space
0, # Zero
1, # Non-zero number
None, # The Void
True, # Boolean True
False # Boolean False
]
print(f"{'OBJECT':<10} | {'TRUTHINESS'}")
print("-" * 25)
for suspect in suspects:
# The bool() function reveals the truth
print(f"{repr(suspect):<10} | {bool(suspect)}")
他们运行了脚本。证据不容置疑。
OBJECT | TRUTHINESS
-------------------------
[] | False
[1] | True
'' | False
' ' | True
0 | False
1 | True
None | False
True | True
False | False
The Trap of “None”
“注意 None,” Margaret 指出。“它的求值结果是 False,就像空列表 [] 一样。但要小心。空列表相当于一个里面什么都没有的盒子。None 的含义是 根本没有盒子。”
“如果你必须明确知道盒子是否缺失,就必须显式检查:
if items is None:。”
“但是在 99 % 的逻辑中,你不需要去测量盒子或计数其中的项目。你只需要问对象一个问题:你重要吗?”
她轻点屏幕。“此外,if items: 的执行速度比计算长度更快。Timothy,你不仅在写更简洁的代码,还在写更快的代码。”
Margaret的速查表
Truthiness(真值性): 你可以在 if 语句中使用 任何 对象。
-
“Falsy”(假)俱乐部
FalseNone(空值)0或0.0- 空集合:
""、[]、()、{}
-
“Truthy”(真)俱乐部
- 其余所有对象。
-
空白陷阱
" "是 Truthy!如果需要忽略空白字符,请使用if string.strip():。
-
经验法则
- “如果它是空的或为零,则为
False。如果它有内容,则为True。”
- “如果它是空的或为零,则为