Python的秘密生活:关于虚无的真相

发布: (2025年12月23日 GMT+8 12:18)
6 min read
原文: Dev.to

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(真值性)。这不仅仅是布尔值 TrueFalse,而是关于 实质 的。”

她在天平的一侧放了一本厚书。天平倾斜了。

“这个列表里有元素。它有重量。因此,它是 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”(假)俱乐部

    • False
    • None(空值)
    • 00.0
    • 空集合:""[](){}
  • “Truthy”(真)俱乐部

    • 其余所有对象。
  • 空白陷阱

    • " " 是 Truthy!如果需要忽略空白字符,请使用 if string.strip():
  • 经验法则

    • “如果它是空的或为零,则为 False。如果它有内容,则为 True。”
Back to Blog

相关文章

阅读更多 »

Python 日志:从 print() 到生产

使用 print 的问题:python printf'Processing user {user_id}' printf'Error: {e}' 缺少的内容:- 没有时间戳 - 没有日志级别 - 没有文件输出 - Can't fil...