4

__init__idまたはslug引数のいずれかを使用し、両方を使用しないクラスを作成しています。引数が期待どおりであることを確認したいと思います。引数に関する仮定を検証するという特定の目的のためにを使用することは適切であり、良い習慣ですかassert、または引数が期待どおりでない場合は例外を発生させる必要がありますか?

例えば、

def __init__(self, id=None, slug=None):
    assert((id or slug) and not (id and slug))
4

3 に答える 3

10

元の質問(「Pythonで内部の仮定を検証するためにassertを使用するのは悪い習慣ですか?」)に対する答えは明らかにノーです。これは、アサーションが適していることに誰もが同意する1つのことです。しかし、あなたが質問で説明しているのは、内部の仮定の検証ではありません。それは外部の入力の検証です。TypeError、、、別のValueError組み込み例外(または、カスタム例外もありますが、それらは控えめにする必要があります)は、APIのユーザーにはるかに役立つフィードバックを提供します。さらに悪いことに、アサーションは完全に削除される可能性があります(一部の環境では、通常は削除されます) 。つまり、コードはサイレントに間違ったことを実行します。

于 2012-11-23T19:09:08.797 に答える
7

あなたが説明するように、これがコードの健全性に関するものである場合、アサーションを使用するのが適切です。これが入力検証に関するものである場合は、assertを使用しないでください。特に、ユーザーはジャンクを提供することによってアサーションをトリガーできないようにする必要があります。アサートは、プログラムのバグが原因でのみトリガーする必要があります。

編集:コメントから学んだように、Pythonではアサーションを完全にオフにすることもできます(つまり、アサーションは評価されないため、失敗することはありません)。これは、パフォーマンスの問題がある場合は、(アセンブリやCなどの別の言語を使用することを除いて)適切な答えになります。

于 2012-11-23T19:07:52.020 に答える
4

失敗するとアサートがAssertionError発生します。ValueError引数が完全に正しくない場合、またはTypeError引数の数が間違っている関数を呼び出すと、Python標準ライブラリが頻繁に発生します。

検討:

int("15f")     #ValueError
int("15",2,3)  #TypeError

(APIの観点から)自分自身に尋ねる必要がある質問は、関数が不正な入力で発生するのに最も論理的なものはどれですか?どちらを選択する場合でも、エラーが発生した場合にユーザーがエラーの処理方法を理解できるように、十分に文書化してください。

于 2012-11-23T19:07:45.110 に答える