首页 论坛 置顶 理解Python中的真值、假值及空值的隐含意义

正在查看 1 个帖子:1-1 (共 1 个帖子)
  • 作者
    帖子
  • #26188

    隐藏的教义:__bool__ 和真理的设计

    在Python中,真理并不是简单的真(True)和假(False)二元对立。它是意义的反映。Python会问:“在逻辑的上下文中,这个对象对自身有什么描述?”

    为了控制一个对象在布尔上下文中的行为,例如在if语句中,你可以定义__bool__方法。

    让我们重新开始。

    第一部分:解释器的问题

    当Python在布尔上下文中评估一个对象时,如:

    if some_object: 
        ...

    它执行以下顺序:

    1. 调用 some_object.__bool__(),如果已定义。
    2. 如果未定义,则回退到 some_object.__len__()
      • 如果长度为 0,则视为 False。
      • 否则,视为 True。
    3. 如果两者都未定义,则默认为 True

    因此,即使是自定义类也可以定义其自身的真值度量。

    第二部分:编写我们自己的真值

    让我们构造一个简单的对象:一个智慧的容器。

    class Scroll:
        def __init__(self, text):
            self.text = text
    
    现在,让我们观察它的真实性:
    s = Scroll("不要追求真理,只需停止珍视观点。")
    if s:
        print("卷轴在说话。")
    else:
        print("卷轴是沉默的。")
    
    这将始终打印“卷轴在说话。”,因为 Scroll 没有 __bool____len__。Python 默认将所有对象视为 True,除非另有说明。

    现在,让我们赋予它真实的声音:

    class Scroll:
        def __init__(self, text):
            self.text = text
    
        def __bool__(self):
            return bool(self.text.strip())

    现在,观察:

    Scroll(" ") # 行为类似于 False
    Scroll("Peace") # 行为类似于 True

    我们已经教会了我们的对象如何表达它的存在。

    第三部分:回退到 __len__

    如果 __bool__ 没有定义,Python 会查找 __len__

    class WisdomBasket:
        def __init__(self):
            self.sayings = []
    
        def __len__(self):
            return len(self.sayings)

    现在:

    basket = WisdomBasket()
    if basket:
        print("有智慧。")
    else:
        print("篮子是空的。")

    当你的对象代表一个集合,并且真实性与其内容相关时,这一点非常有用。

    第四部分:将真实性作为设计决策

    这有什么重要性?

    因为在现实世界的代码中,真实性通常意味着意义。考虑一下:

    if response:
        ...

    响应应该意味着什么?

    • HTTP请求是否成功?
    • 响应体是否包含有用的数据?
    • 状态码是否为200?

    你决定__bool__应该传达什么。

    在设计API、内部库或用户定义的类时,清晰的真值定义可以减少样板代码,使意图显而易见。

    第5部分:关于模糊性的警告

    真值应该是明确且直观的。

    如果你的对象代表一个配置、请求或资源,考虑“真值”意味着什么。避免那些使逻辑变得模糊的聪明做法:

    if config:
        # 这意味着什么?

    最好进行文档记录,或者在语义不明确的情况下完全避免使用真值。

    结束循环

    大师没有说:“空列表是 False。”
    他说:“不是 false。只是空。”

    在 Python 中,真值并不是固定的。它是由你的设计投射的阴影。你可以选择你的对象如何反射光线,或者光线的缺失。

正在查看 1 个帖子:1-1 (共 1 个帖子)
  • 哎呀,回复话题必需登录。