1

私たちのプロジェクトはやや大きくなりつつあり、先日、関数に簡単なエラーメッセージを追加しようとしたときに、この問題が発生しました。

def create_report(id):
    report = new_report(id)
    if not report:
        raise api_error('Could not find report with id %d' % (id,))
    ...

問題? id文字列であり、数値としてフォーマットしようとするとクラッシュしました。私は関数の元の作者ではなく、それidが数字であると誤って想定していました。代わりに、文字列であると想定されています。おっと。

これが強く型付けされた言語である場合、コンパイラからすぐにエラーが発生します。この種のことを行うための最良の方法は何ですか?すべてのパラメーターのタイプをチェックする必要がありますか(多くのレッグワークのように見えます)、それともすべてをtry:ブロックに入れる必要がありますか?たぶん、すべての関数にそのパラメーターを説明するコメントを書く必要がありますか?それとも、私は単にもっとよく知っているはずだったのでしょうか?

4

6 に答える 6

2

そのフォーマット文字列は、文字列である%sためではなく、id一般的に最良の選択であるため、使用する必要がありました。%d数値型が%s必要ですが、必要に応じて他の型を文字列に変換します。%d数値の書式を変更する必要がある場合にのみ使用してください。

于 2012-09-08T16:02:11.910 に答える
0

パラメータタイプに関してそのようなものをより堅牢にするための可能な戦略は、次のように書くことです。

def create_report(id):
    report = new_report(id)
    if not report:
        raise api_error('Could not find report with id %s' % (id,))
    ...

見栄えが良いとは限りませんが、少なくとも簡単に壊れることはありません。

ただし、一般的には、関数の明示的なコントラクトを用意することをお勧めします。docstringはそのための適切な場所です。

于 2012-09-08T16:02:21.903 に答える
0

文字列印刷関数がクラッシュしないことを本当に確認したい場合は、%s を使用するのがおそらく最善です。これは、統合された値を pythons str() 関数を使用して文字列に変換します。そして、それがあなたが話しているIDであることを見て、それがint型であると仮定します-その場合、この解決策はうまくいくはずです(フロートを使用している場合、何桁かわかりません str()保持します)。

編集 ああ、私は遅いです...

于 2012-09-08T16:08:10.980 に答える
0

%s を使用してから、str(変数) を使用してみてください。これにより、すべてが文字列に変換され (リストやタプルも)、TypeError が発生しないことが保証されます。

def create_report(id):
    report = new_report(id)
    if not report:
        raise api_error('Could not find report with id %s' % (str(id),))
    ...
于 2012-09-08T16:12:39.137 に答える
0

他の回答よりも優れていますが、メッセージが開発者の目に向けられている場合は、%s使用するのが最適です。%rこれは、微妙なケースを区別するのに役立ちます。たとえば'12 '、id を指定してこの関数を呼び出した場合、%s メッセージは末尾のスペースを表示しません。 %r値の repr() を使用するため、引用符が含まれるため、正確な値を確認するのに役立ちます。

于 2012-09-08T16:18:37.690 に答える
0

ここでの問題は、何か予期しないことが起こったときに実行されるコードの一部の値について何かをアサートすることだと思います。new_report(id)おそらく、何か問題が発生した場合に例外を発生させるように変更することをお勧めします-それが値エラーであるか、IDが見つからないかを指定します。次に、コードは次のようになります。

def create_report(id):
    report = new_report(id)

...

def new_report(id):
    try:
       # find the report by id
       # if couldn't find raise api_error
    except ValueError:
       # explain that id is the wrong type
于 2012-09-08T17:42:31.410 に答える