Pythonで変数の存在確認 未定義判定のサンプルコード

Pythonで変数の存在確認

Pythonの未定義安定

当時私は新入社員として、あるWebサービスの開発プロジェクトに携わっていました。 担当したのは、ユーザーの購入履歴に基づいておすすめ商品を表示する機能です。意気揚々と開発を進め、テストも問題なく完了。自信満々で本番環境にリリースしました。

しかし、リリースから数日後、想定外の事態が発生しました。一部のユーザーに、全く関係のない商品が表示されてしまうという不具合が報告されたのです。調査の結果、原因は私のコードにあることが判明しました。

問題点は、変数の名前のスペルミスでした。

purchase_historyという変数名を使用するべきところを、誤ってpurchase_hisotryと記述していたのです。たった1文字の違いなのに、プログラムは全く異なる意味として解釈し、誤った商品を表示していたのです。

この不具合の影響は深刻でした。ユーザーは混乱し、信頼を失墜。さらに、誤った商品購入によるキャンセルや返品が相次ぎ、会社は100万円以上の損失を被りました。

この失敗は、変数の未定義チェックを怠っていたことが原因です。 コードレビューの際に、スペルミスを見逃してしまっていたのです。

Pythonの未定義変数を判定

Pythonの未定義変数判定&チェックツール

Pythonで未定義変数を使用すると、原因不明なエラーが発生したり、プログラムが不安定になったりする可能性があります。また、プログラムが実行されると不必要なメモリを使用する可能性があります。また、未定義変数を使用すると、コードを理解しにくくなる可能性もあります。

そのため、変数が未定義かどうかを判定する必要が出てくるんですね。try~exceptでNameErrorをキャッチすることで未定義判定ができます。

以下は、変数nameが未定義かどうか判定するサンプルコードです。

try:
    print(name)
except NameError:
    print('変数nameが未定義です。')

変数nameで例外NameErrorが発生した場合に、未定義であるというメッセージを表示します。NameErrorます。

変数nameが未定義です。

上記の例では、変数ごとにtry~exceptを指定しないと未定義変数の出現箇所がわかりません。

Pythonでは、変数名をタイプミスして値を代入しても特に警告も出ないので、バグに気づきにくいという可能性があるんですね。

Pythonのコード内で未定義変数に値を代入している箇所をチェックするには、pyflakesというツールを使うと良いでしょう。 pyflakesは、Pythonコード内で未定義変数を検出するツールです。pyflakesは無料で利用できるオープンソースのツールなので、お手軽に使うことができます。

参考)pyflakes · PyPI

Pythonの未定義関数

Pythonの未定義関数判定のサンプルコード

関数が未定義かどうかは、関数呼び出し時にNameError例外が発生するかどうかで判定できます。

def is_defined(function_name):
try:
    eval(function_name)
return True
    except NameError:
return False

if __name__ == '__main__':
    print(is_defined('print'))
print(is_defined('foo'))

eval関数は、文字列を実行可能なPythonコードとして評価する関数です。関数を指定した場合、その関数を実行し、その結果を返します。

実行するとこうなります。print関数は定義済み、foo関数は未定義という判定になりました。

True
False

関連)Pythonのdefで関数を定義

Pythonの未定義配列

Pythonの空配列=未定義配列

Pythonの配列は、空だと未定義扱いになります。未定義かどうかを判定するサンプルコードは以下の通り。notを使って未定義配列の判定が可能です。

 

arr = []

if not arr:
    print('未定義')

実行するとこうなります。arrは空の配列ですが、notを使って判定すると未定義となりました。

未定義

関連)Pythonの配列

Pythonの未定義辞書

Pythonの辞書で未定義のキーを判定

inを使って辞書の未定義の判定が可能です。

以下は、辞書にOrangeというキーが定義されているかどうかを判定するサンプルコードです。

my_dictionary = {
'Apple': '小さな青い果物',
'Banana': '黄色い果物'
}

key = 'Orange'

if key in my_dictionary:
print(f'{key} の値は {my_dictionary[key]} です。')
else:
print(f'{key} は未定義です。')

実行するとこうなります。

Orange は未定義です。

関連)Pythonのdictは辞書型

Pythonの未定義のまとめ

Pythonのみ定義判定のまとめ

  • Pythonで未定義の変数や関数はNameError例外が発生するかどうかで判定する
  • 配列の未定義判定はnotを使って判定する
  • 辞書に指定のキーが定義済みかどうかは、inを使って判定する