You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中实现类SQL NULL风格的三值逻辑?

实现SQL风格的三值逻辑

由于Python原生的and/or是短路运算符,其行为由对象的布尔值决定,无法直接重载以适配三值逻辑的完整规则,因此我们可以通过自定义单例类实现符合SQL NULL逻辑的三值布尔类型,使用重载的运算符替代原生逻辑运算符,同时满足is判断的需求。

实现代码

class TriBool:
    """实现SQL风格三值逻辑的布尔类型(True/False/Unknown)"""
    def __init__(self, value):
        self._value = value  # 0: False, 1: True, 2: Unknown

    # 定义单例实例
    TRUE = None
    FALSE = None
    UNKNOWN = None

    def __repr__(self):
        return {0: "TriBool.FALSE", 1: "TriBool.TRUE", 2: "TriBool.UNKNOWN"}[self._value]

    def __eq__(self, other):
        return isinstance(other, TriBool) and self._value == other._value

    def __and__(self, other):
        """重载&运算符,对应三值逻辑的AND"""
        # 自动转换普通布尔值为TriBool实例
        if not isinstance(other, TriBool):
            other = TriBool.TRUE if other else TriBool.FALSE
        # 对应真值表的AND规则
        lookup = {
            (1, 1): 1, (1, 2): 2, (1, 0): 0,
            (2, 1): 2, (2, 2): 2, (2, 0): 0,
            (0, 1): 0, (0, 2): 0, (0, 0): 0
        }
        return TriBool(lookup[(self._value, other._value)])

    def __rand__(self, other):
        """处理左操作数不是TriBool的情况(如True & UNKNOWN)"""
        return self & other

    def __or__(self, other):
        """重载|运算符,对应三值逻辑的OR"""
        if not isinstance(other, TriBool):
            other = TriBool.TRUE if other else TriBool.FALSE
        # 对应真值表的OR规则
        lookup = {
            (1, 1): 1, (1, 2): 1, (1, 0): 1,
            (2, 1): 1, (2, 2): 2, (2, 0): 2,
            (0, 1): 1, (0, 2): 2, (0, 0): 0
        }
        return TriBool(lookup[(self._value, other._value)])

    def __ror__(self, other):
        """处理左操作数不是TriBool的情况(如False | UNKNOWN)"""
        return self | other

    def __invert__(self):
        """重载~运算符,对应三值逻辑的NOT"""
        lookup = {1: 0, 0: 1, 2: 2}
        return TriBool(lookup[self._value])

    def __bool__(self):
        """禁止隐式转换为普通布尔值,避免混淆"""
        raise TypeError("TriBool cannot be implicitly converted to bool. Use explicit comparison instead.")

# 初始化单例
TriBool.TRUE = TriBool(1)
TriBool.FALSE = TriBool(0)
TriBool.UNKNOWN = TriBool(2)

使用示例

# 基础赋值
t = TriBool.TRUE
f = TriBool.FALSE
n = TriBool.UNKNOWN

# AND运算
print(t & t)  # TriBool.TRUE
print(t & n)  # TriBool.UNKNOWN
print(n & f)  # TriBool.FALSE

# OR运算
print(f | n)  # TriBool.UNKNOWN
print(n | t)  # TriBool.TRUE
print(n | n)  # TriBool.UNKNOWN

# NOT运算
print(~t)     # TriBool.FALSE
print(~n)     # TriBool.UNKNOWN

# is判断
print(t is TriBool.TRUE)  # True
print(n is TriBool.FALSE) # False

关键说明

  1. 单例设计:通过类属性维护三个唯一实例,确保is判断可以准确识别状态。
  2. 运算符重载:用&替代and、|替代or、~替代not,完全匹配你提供的真值表规则。
  3. 类型兼容:支持与普通布尔值混合运算,自动转换为TriBool实例。
  4. 避免混淆:禁止隐式转换为普通布尔值,防止因原生短路逻辑导致的非预期行为。

内容的提问来源于stack exchange,提问作者Artimis Fowl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 15:34:53