Pythonのプログラミング、エラーと例外との向き合い方

目次

この記事は以下の方を対象としています。

  • Pythonによる自動処理をされている方
  • Pythonのエラーと例外への対応方法を知りたい方
  • 例外発生時も、自動処理を継続したい方
  • 例外発生時のエラーメッセージを記録したい方

本コラムのゴール

  • Pythonにおけるエラーと例外への対応方法を理解できる
  • VSCodeの拡張機能:Pylanceを使い、コードの間違っているところを確認できる
  • Pythonのプログラムで例外が発生しても、自動処理を継続できる
  • Pythonのプログラムで例外が発生したとき、記録に残すことができる

エラーと例外との向き合い方

みなさんの中には、職場ではじめてPythonを使い始めるという方も多いと思います。

今回は、初めてPythonを使う方や、プログラミングに挑戦される皆様に、エラーと例外への対応方法についてお話しさせていただきます。

エラーや例外は、誰でも経験します。プログラムに問題がなくとも、データ側に問題のある場合もあります。エラーや例外は起こるものと考え、どのように向き合えばよいかお話させていただきます。

本日は、以下の順番でお話をさせていただきます。

1.自分を知る(人は同じ過ちを繰り返す)
2.エラーの内容を知る
3.エラーを防ぐ
4.エラーがあっても処理を止めない
5.エラーを記録する

1.自分を知る(人は同じ過ちを繰り返す)

何事も、人間は同じ過ちを何度も繰り返すものです。プログラミングも例外ではありません。特に初心者のうちは、同じミスを繰り返すことがよくあります。

私の経験をお話しします。私は、プログラミングを始めたばかりの頃、if文の末尾にコロン(:)を付け忘れるというミスを何度もしました。しかし、何度も同じミスをするうちに、正しい書き方を自然と身についていくことができました。なぜなら、コロンを付け忘れるとプログラムが動かないからです。プログラムを正しく動かすためには、正しい書き方を習得するしかありません。

このように、人は同じ誤りを繰り返しがちです。そして、誰もがしやすい間違いというものがあります。そこで、よくある間違いをリストアップしてみました。このように、よくあるミスをリスト化しておくと、自分自身の成長に役立ちます。

人はどんなエラー・例外をしてしまうか

  • if文のコロン(:)の付け忘れ
  • インデントの不一致・ずれ
  • クォーテーションの閉じ忘れ
  • 変数名のスペルミス
  • 大文字小文字の区別ミス
  • インデックスの範囲外の指定
  • データ型の不一致
  • 必要なモジュールのインポートの忘れ
  • 数値を文字列に変換しないまま、文字列と結合

これらは初心者がよく犯す間違いです。何度も同じミスを繰り返すことで、次第に正しい書き方を学び、成長していきます。大切なのは、ミスを恐れずに学び続けることです。ミスをリストアップし、再発防止に努めることで、プログラマーとしてのスキルは確実に向上します。

2.エラーの内容を知る

エラーが発生した場合、そのエラーメッセージを正確に理解することが重要です。エラーメッセージは、問題の原因を特定するための手がかりとなります。Pythonのエラーメッセージには、エラーの種類(例:SyntaxError、TypeError)、エラーが発生した行番号、そしてエラーの詳細な説明が含まれています。

最近では、生成AIを利用してエラーの内容を確認する方法もあります。生成AIにエラーメッセージを入力すると、具体的な解決方法を提案してくれる場合があります。ただし、エラーメッセージの中にパソコンに関する個人情報が含まれている場合、その情報が生成AIの学習データとして使用される可能性があるため、セキュリティ、プライバシーに注意が必要です。

例えば、以下のようなエラーメッセージが表示されたとします:

Traceback (most recent call last):
  File "example.py", line 2, in <module>
    print(10 / 0)

ZeroDivisionError: division by zero

このメッセージは、example.pyファイルの2行目でゼロ除算が発生したことを示しています。エラーの種類はZeroDivisionErrorであり、詳細な説明として「division by zero」と記載されています。この情報をもとに、ゼロで除算しないようにコードを修正することができます。

3.エラーを防ぐ

エラーを未然に防ぐためには、コードの品質を向上させるツールを活用することが重要です。特にVisual Studio Code(VSCode)を使用している場合、マイクロソフトが提供する拡張機能「Pylance」を導入することをお勧めします。Pylanceは静的解析ツールといい、プログラムを実行する前の状態で、エラーの可能性がある箇所を指摘してくれます。

①セットアップ

Pylanceをインストールするには、VSCodeの拡張機能の検索欄に「Pylance」を入力して検索し、マーケットプレイスからインストールします。

図1 拡張機能検索画面

拡張機能検索画面

インストール後、「Pylance」を選択し、「有効にする」を選択し、Pylanceを有効にします。

図2 Pylanceを有効にする

Pylanceを有効にする

②Pylanceの使い方(エラーの表示)

Pylanceはリアルタイムでコードを解析し、エラーや警告を表示します。エラーが検出されると、問題のある行に赤い波線が表示され、マウスカーソルを合わせるとエラーメッセージがポップアップ表示されます。

以下の画面は、if文のコロン(:)の付け忘れのため、赤い波線を表示しています。

図3 Pylanceの動作見本

Pylanceの動作見本

4.エラーがあっても処理を止めない

自動処理では、エラーが発生しても処理を停止せずに継続することが大切です。例えば、10000個のデータの自動処理を進めていて、100個目のデータの処理でプログラムが停止し、それに気づかず、残りの9900個の処理ができていなかったということの無いようにする必要があります。

あるデータがエラーになって処理できなくても、その1つのエラーでプログラムが停止することなく、全体の処理を継続することができるようにします。

以下のプログラムは、エラーで停止せずに継続処理できるようにしています。tryブロック内で、リストの各要素を使って10を割る計算を試みます。次の2つのエラーが発生する可能性があります。

ZeroDivisionError: ゼロで割ろうとした場合に発生します。

このエラーが発生すると「0で割ることはできません。」というメッセージが表示され、continueによってループが次の要素に進みます。

TypeError: 非数値(この場合は文字列)で割ろうとした場合に発生します。

このエラーが発生すると「文字列で割ることはできません。」というメッセージが表示され、continueによってループが次の要素に進みます。

list_a = [-2, -1, 0, 1, "A", 2]

for value in list_a:
    try:
        result = 10 / value
        print(f"10 / {value} = {result}")
    except ZeroDivisionError:
        print("0で割ることはできません。")
        continue
    except TypeError:
        print("文字列で割ることはできません。")
        continue

このように、エラーが発生してもプログラム全体が停止することなく、次の処理に進むことができます。これにより、特定のデータで問題が発生しても、他のデータの処理を継続することができるため、より堅牢な自動処理が実現できます。

5.エラーを記録する

プログラムがエラーを発生した際に、そのエラーを記録しておくことは非常に重要です。これにより、後からエラーの原因を分析し、適切な対策を講じることができます。このプロセスを「ログの取得」と言います。

①ログを取得するとは

ログを取得するとは、プログラムの実行中に発生したイベントやエラーの詳細をファイルに記録することです。これにより、プログラムがどのように動作したか、どのような問題が発生したかを後から確認することができます。

②ログファイルとは

ログファイルは、プログラムの実行中に発生したエラーやその他の重要なイベントの詳細を記録するファイルです。このファイルには、エラーの種類、発生時刻、エラーの内容などが含まれます。

③ログファイルの保存場所

ログファイルは通常、プログラムと同じディレクトリに保存されますが、必要に応じて特定のディレクトリに保存することも可能です。ファイル名や保存場所は、設定ファイルやコード内で指定します。

以下のプログラムは、エラーをログファイルに記録する方法を示しています。

import logging
from datetime import datetime

# ロガーの設定
logging.basicConfig(
    filename="error_log.log",
    level=logging.ERROR,
    format="%(asctime)s - %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)

list_a = [-2, -1, 0, 1, "A", 2]

for value in list_a:
    try:
        result = 10 / value
        print(f"10 / {value} = {result}")
    except ZeroDivisionError as e:
        error_message = f"0で割ることはできません。 - エラーメッセージ: {e}"
        print(error_message)
        logging.error(f"ZeroDivisionError: {e} - 値: {value}")
    except TypeError as e:
        error_message = (f"文字列で割ることはできません。 - エラーメッセージ: {e}")
        print(error_message)
        logging.error(f"TypeError: {e} - 値: {value}")

④ロガーの設定

「# ロガーの設定」の部分では、loggingモジュールを使用してロガーを設定しています。filenameでログファイルの名前を指定し、levelで記録するログのレベルを設定します。この場合、エラーレベルのログのみを記録します。formatとdatefmtで、ログメッセージの形式と日付の形式を指定します。

tryブロック内で、リストの各要素を使って10を割る計算を試みます。次の2つのエラーが発生する可能性があります:

ZeroDivisionError: ゼロで割ろうとした場合に発生します。このエラーが発生すると、エラーメッセージを表示し、ログファイルにエラーの詳細を記録します。

TypeError: 非数値(この場合は文字列)で割ろうとした場合に発生します。このエラーが発生すると、エラーメッセージを表示し、ログファイルにエラーの詳細を記録します。

⑤実行結果

このプログラムを実行すると、コンソールには次のような出力が表示され、error_log.logファイルにはエラーの詳細が記録されます:

10 / -2 = -5.0
10 / -1 = -10.0
0で割ることはできません。 - エラーメッセージ: division by zero
10 / 1 = 10.0
文字列で割ることはできません。 - エラーメッセージ: unsupported operand type(s) for /: 'int' and 'str'
10 / 2 = 5.0

error_log.logファイルの内容は次のようになります:

2024-07-04 10:00:00 - ZeroDivisionError: division by zero - 値: 0
2024-07-04 10:00:01 - TypeError: unsupported operand type(s) for /: 'int' and 'str' - 値: A

このように、エラーをログファイルに記録することで、後からエラーの発生状況を確認し、分析することができます。

まとめ

Pythonは、オープンソースソフトウェアなので、無償で使えることもあり、勉強する方、活用される方が増えています。乗り遅れることなく、この流れの中に入りましょう。

現在、Pythonを使っている方のお話を聞くと、Pythonの将来性を感じて勉強を始めたとのお話を聞きます。現在、人気の高いプログラミング言語であり、将来、活躍の幅が広がることと思います。

今回は、エラーと例外との向き合い方について解説しました。

また、Pythonを活用した自動化ソリューションに興味がある方は以下のページをご覧ください。

https://gw-Python.com/Python-auto

この記事が気に入ったら
いいね または フォローしてね!

  • URLをコピーしました!
  • URLをコピーしました!
目次