使用class作为特殊值?

时间:2013-10-03 12:50:07

标签: python class

在Python中使用class作为特殊值是否很难看?

考虑一下:

def find_result():
    result = None
    # do something to find the result, even recursing
    return result

r = find_result()
if r is None:
     raise Exception("we have no result")

如果我希望结果是数字或任何“普通”类型,这是完美的。

但是,如果存在任意数据结构,结果可以是从None到另一个结构的任何内容呢?在我的案例中我做的是:

class NoResult:
    """i'm even less than `None`."""
    pass

def query(data, path):
    result = NoResult
    # traverse and recurse into the data structure
    return result

r = query()
if r is NoResult:
     raise Exception("our hands are empty")

它有效,但我无法摆脱这种感觉,我有点滥用这里的贫困阶层,甚至可能潜伏在里面。

这是真的吗?我在上课吗?或者只是我的算法很糟糕,如果它需要依赖这样的“特殊None”?

2 个答案:

答案 0 :(得分:5)

它被称为哨兵,您可以使用任何唯一的对象:

sentinel = object()

if r is sentinel:
    raise Exception(..)

这里我使用了一个简单的object()实例而不是自定义类。

自定义类确实具有可能更自我记录的优势;如果你的API 将对象传递给API的用户(可以是代码),那么显式类更好。只需在API的黑盒子中使用,object()就可以了。

您可能想要考虑仅在您现在返回哨兵时提出异常。您可以随时捕获异常。

答案 1 :(得分:2)

只是为了添加Martijn建议的另一种方法,就是使用例外机制让find_result首先抛出“无结果”异常,然后让调用者决定如何处理它。 / p>

def find_result():
    result = None
    if (...):
        raise NoResultException("details")
    return result

try:
    r = find_result()
except NoResultException:
     raise Exception("we have no result")