使用类作为特殊值?

2024-04-16 15:44:18 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中使用类作为特殊值是不是很难看?你知道吗

考虑一下:

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”,那它就糟透了?你知道吗


Tags: thenonedatareturnifisdefexception
2条回答

它被称为哨兵,你可以为它使用任何独特的对象:

sentinel = object()

if r is sentinel:
    raise Exception(..)

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

自定义类的优点是它可能更易于自文档化;如果您的API将对象传递给API的用户(可以是代码),那么显式类更好。仅在API的黑盒中使用object()就可以了。你知道吗

您可能需要考虑在您现在返回sentinel的地方引发异常。您总是可以再次捕获异常。你知道吗

为Martijn建议的方法添加另一种方法,就是使用异常机制让find_result首先抛出一个“无结果”异常,然后让调用者决定如何处理它。你知道吗

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

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

相关问题 更多 >