2016-12-28 3 views
2

私のコードは正常に動作していますが、PyCharmは次の点でexcept節について警告しています。正直なところ、間違った実装として私にも匂いがする。Python:私のexcept節は実際には広すぎますか?

HTML <tr>を一括して掻き集めると、データベースやアップデートに追加する必要があります。ゲームが終了したかどうかは事前にわかりません。また、完了していないゲームでは、異なるハンドリングが必要な、いくつかのHTMLタグがあります(<td>)。

基本的にmatch_score_stringmatch_relevant_bitを見ると、BeautifulSoupに特定のクラスの<td>が見つかっています。ゲームが既に終了している場合、この<td>score-time scクラスになります。そうでなければ、score-time stクラスになります。それがある場合、それは他を持っていません。

それは私がtry-except句を書いてからしばらくして、私が正しくリコール場合BSはエラーをスローし、row.findはHTMLを見つけるために失敗したときにすべての操作を停止してしまうようなので、私はそれらを使用しなければならなかった理由は(私が感じた)であるですオブジェクト。

PyCharmは正当に不平を言っていますか?

# Get Match Score 
try: 
    match_score_string = row.find("td", class_="score-time sc").get_text() 
    match_string_split = match_score_string.split(" - ") 
    team_a_score = int(match_string_split[0]) 
    team_b_score = int(match_string_split[1]) 
    print(team_a_score) 
    print(team_b_score) 
except: 
    team_a_score = None 
    team_b_score = None 

# Get Match URL 
try: 
    match_relevant_bit = row.find("td", class_="score-time sc") 
    match_url = match_relevant_bit.find("a").get("href") 
    match_url_done = match_url.rsplit('?JKLMN') 
    match_url = match_url_done[0] 
    match_finished = True 

except: 

    match_relevant_bit = row.find("td", class_="score-time st") 
    match_url = match_relevant_bit.find("a").get("href") 
    match_url_done = match_url.rsplit('?JKLMN') 
    match_url = match_url_done[0] 
    match_finished = False 

答えて

3

exceptは確かに広すぎます。私はあなたがこれらのケースで例外処理を必要とするかどうか争うことはありません - 例外は非常にpythonであるので、あなたが適切だと思うところはどこでも使用してください。しかし、を処理するコードが必要であると主張していない場合は、すべて例外を想像してください。裸の例外はあらゆる種類のバグを隠すことができます。例えばあなたが以降のリビジョンで、変数名のスペルを間違えると:...

try: 
    match_score_string = row.find("td", class_="score-time sc").get_text() 
    match_string_split = match_score_string.split(" - ") 
    team_a_score = int(match_string_spilt[0]) # oops 
    team_b_score = int(match_string_split[1]) 
    print(team_a_score) 
    print(team_b_score) 
except: 
    team_a_score = None 
    team_b_score = None 

ベアexceptsでもプログラムを終了するKeyboardInterruptを送信するからユーザーを防ぐ

をしたくない理由は、これらはわずか2例がありますbare except - これによってマスクされる可能性のあるプログラミングエラーの数は無限に近いので、私はそれらのすべてを実証するのに十分な時間がありません;-)。

代わりに、あなたが遭遇すると予想まさに例外を指定する必要があります

try: 
    match_score_string = row.find("td", class_="score-time sc").get_text() 
    match_string_split = match_score_string.split(" - ") 
    team_a_score = int(match_string_spilt[0]) # oops 
    team_b_score = int(match_string_split[1]) 
    print(team_a_score) 
    print(team_b_score) 
except AttributeError: # If no row is found, accessing get_text fails. 
    team_a_score = None 
    team_b_score = None 

この方法は、あなたがを期待するように、コードが実行されるとあなたは(あまりにも多くの)プログラミングのバグを隠していません。バグを隠蔽しないようにしたいのは、例外ハンドラ内のコード量をできるだけ制限することです。

+0

別のケースは、この種のtryブロックで呼び出されたときに動作しない 'sys.exit()'です。 –

+0

@JossefHarush - もちろんです。あるいは 'assert'ステートメントや...何かに失敗しました。 :-) – mgilson

+0

'try'節のコードで発生した例外を具体的に処理するのではなく、' KeyboardInterrupt'や 'RuntimeError'のような外部例外を処理する方法についてどう思いますか?伝統的な例外処理は、 '' try'( "find"や不可能なint型キャストのような)で "直接"引き起こされたエラーを処理することですが、OPはこれらの例外をすべて同じ方法で処理したいと考えていますあなたが書いたように、 'KeyboardInterrupt'のような外部例外は、別の注意で扱われるべきです。 –

0

試してください/ except節は素晴らしいです。あなたはあまりにも頻繁にそれらを使用しないように聞こえる。

try/exceptブロックは、あなたがあれば、複雑な文、または時々あなたが(:P私がやったことを参照)を行うに INGを試しが何であるか、それは不明で作ることができ、次に進む前の状態をチェックするコードを避けるのを助けることができます。

コードからドラッグする可能性があり、その中には他のものよりも可能性が高い例外がいくつかあります。以下を参照してください:

try: 
    # This first line could have an AttributeError in two places 
    #  Maybe the row didn't parse quite correctly? find() won't work then. 
    #  Maybe you didn't find any elements? get_text() won't work then. 
    match_score_string = row.find("td", class_="score-time sc").get_text() 
          ^        ^
    # Same as here, you could get an AttributeError if match_score_string isn't a string. 
    #  I would say that isn't very likely in this case, 
    #  Especially if you handle the above line safely. 
    match_string_split = match_score_string.split(" - ") 

    # If either of these split strings contains no matches, you'll get an IndexError 
    # If either of the strings at the index contain letters, you may get a ValueError 
    team_a_score = int(match_string_split[0]) 
    team_b_score = int(match_string_split[1]) 

    # Theoretically, if you caught the exception from the above two lines 
    #  you might get a NameError here, if the variables above never ended up being defined. 
    print(team_a_score) 
    print(team_b_score) 
except: 
    # Can't really imagine much going wrong here though. 
    team_a_score = None 
    team_b_score = None 

想像されるように、いくつかのタイプの例外をキャッチする方が便利かもしれません。入力の複雑さによって異なります。

複数のtry/exceptブロックは、特にエラーをキャッチし、そのブロック内の残りのコードの実行を続ける必要がある場合に役立ちます。

+0

ありがとうVasili。私が@ mgilsonの答えを正しく理解していれば、私の考えを確認しました。目標は* more *ではなく* less * errorsを一度に捕まえることです。また、あなたが組み込んだコードは、2番目のタイプの '​​'を扱っていないと思います。その場合、別のデータをデータベースに書き込む必要があります。 – zerohedge

+0

はい、理想的には、できるだけ 'try'ブロックで起こっていることがほしいと思うのが理想です。私は、複数の例外にどのように分けることができるかを説明するために、例の1つだけを取り上げました。物事をどのように扱いたいかによって異なります。 –

関連する問題