3

クラスを特別な値として使用するのは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ですか?

4

2 に答える 2

5

これはセンチネルと呼ばれ、任意の一意のオブジェクトを使用できます。

sentinel = object()

if r is sentinel:
    raise Exception(..)

ここでobject()は、カスタム クラスの代わりに単純なインスタンスを使用しました。

カスタム クラスには、おそらくより自己文書化できるという利点があります。APIAPIのユーザー (コードの場合もある) にオブジェクトを渡す必要がある場合は、明示的なクラスの方が適切です。API のブラック ボックスで使用するだけでobject()十分です。

センチネルを返す時点で例外を発生させることを検討することをお勧めします。例外はいつでもキャッチできます。

于 2013-10-03T12:52:03.717 に答える
2

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")
于 2013-10-03T12:59:53.787 に答える