Pythonのデコレーターを巧みに使ってif...elif...elseを処理する
この方法がどのようなものか、具体的に見てみましょう。例えば、ユーザーのランクに応じて、そのユーザーが受けられる割引を決める関数を作りたいとします。通常のif ... elif ... は、このように書くことになる。
def get_discount(level):
if level == 1:
"Bulk calculation code"
discount = 0.1
elif level == 2:
"Bulk calculation code"
discount = 0.2
elif level == 3:
discount = 0.3
elif level == 4:
discount = 0.4
elif level == 5:
discount = 0.5
elif level == 6:
discount = 3 + 2 - 5 * 0.1
else:
return 'Level error'
return discount
ご存知のように、このような大量の
if ... elif...
のコードは非常に見づらく、メンテナンスも大変です。そして、それぞれのifの内部にはたくさんのコードがあります。そうすると、関数がとても長く引き延ばされてしまいます。
この長すぎるif判定を辞書を使って書き換えることができることを知っている学生もいます。
def parse_level_1():
"Bulk calculation code"
discount = 0.1
return discount
def parse_level_2():
"Bulk calculation code"
discount = 0.2
return discount
def parse_level_3():
"Bulk calculation code"
discount = 0.3
return discount
def parse_level_4():
"Bulk calculation code"
discount = 0.4
return discount
def parse_level_5():
"Bulk calculation code"
discount = 0.5
return discount
def parse_level_6():
"Bulk calculation code"
discount = 3 + 2 - 5 * 0.1
return discount
discount_map = {
1: parse_level_1,
2: parse_level_2,
3: parse_level_3,
4: parse_level_4,
5: parse_level_5,
6: parse_level_6,
}
discount = discount_map.get(level, 'level error')
でも、今日習ったこの方法は、辞書を使うよりも簡単なんだ。その方法を見てみましょう。
@value_dispatch
def get_discount(level):
return 'Level error'
@get_discount.register(1)
def parse_level_1(level):
"Bulk calculation code"
discount = 0.1
return discount
@get_discount.register(2)
def parse_level_2(level):
"Bulk calculation code"
discount = 0.2
return discount
@get_discount.register(3)
def parse_level_3(level):
"Bulk calculation code"
discount = 0.3
return discount
@get_discount.register(4)
def parse_level_4(level):
"Bulk calculation code"
discount = 0.4
return discount
@get_discount.register(5)
def parse_level_5(level):
"Bulk calculation code"
discount = 0.5
return discount
@get_discount.register(6)
def parse_level_1(level):
"Bulk calculation code"
discount = 3 + 2 - 5 * 0.1
return discount
discount = get_discount(3)
print(f'The user with level 3, the discount received is: {discount}')
実行結果は、以下の画像のようになります。
このように書くと、辞書を使うよりも直感的で、単に
if ... elif...
はより簡潔です。
そこで、このデコレータ
value_dispatch
どのように実装されているのでしょうか?パスワードは、このオープンソースプロジェクトに隠されています。
EdgeDB
のソースコード[2]にある、20行強のコアコードで構成されています。
そして、それを実装したり、問い合わせることも可能です。例えば、ユーザーレベルが2または3で、割引が0.2の場合、以下のようにコードを記述することができます。
@get_discount.register(2)
@get_discount.register(3)
def parse_level_2(level):
"Bulk calculation code"
discount = 0.2
return discount
実行結果は、以下の画像のようになります。
このコードでは、現在、イコールクエリしかできません。しかし、実はこのコードに少し手を加えるだけで、より大きい、より小さい、以上、以下、以下、等しくない、そして
in
といった具合です。もし興味があれば、記事の下にコメントを残してください。明日、このコードを修正してより論理的な判定を実装する方法についてお話します。
参考文献
[1] EdgeDB。 https://github.com/edgedb/edgedb
[2] ソースコード https://github.com/edgedb/edgedb/blob/master/edb/common/value_dispatch.py
技術交流
転載、ブックマーク、応援よろしくお願いします。
Pythonのデコレータを巧みに使ってif. .elif.. ...elseを処理する記事はこちらで紹介していますが、もっと関連するPythonデコレータのコンテンツは、スクリプトハウスの過去の記事を検索してください。
関連
-
Pythonを使って簡単なzipファイルの解凍パスワードを手作業で解く
-
[解決済み】PythonのTypeErrorはintではなくstrでなければならない【重複あり
-
[解決済み] [Solved] Map to List エラー。シリーズオブジェクトを呼び出すことはできません
-
[解決済み] Pipenv: コマンドが見つかりません
-
[解決済み] KeyError / フリーズしたimportlib._bootstrapがspyderの2つ目のライブラリインポートでエラーになる。
-
[解決済み] 同じ行に前の出力を上書きして出力しますか?
-
[解決済み] scipy.sparse.csr_matrixの例を理解できない。
-
Python3 reports TypeError: '***' object is not iterable.
-
Pythonの個別変数のクリアとコンソールのクリーンアップ
-
UnicodeDecodeError: 'ascii' コーデックは、ポジションソリューションのバイト 0xe6 をデコードできません。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Evidentlyを用いたPythonデータマイニングによる機械学習モデルダッシュボードの作成
-
[解決済み】Python [Errno 98] アドレスはすでに使用中です。
-
[解決済み】TypeError: 'newline' is an invalid keyword argument for this function [重複] この関数のキーワード引数は無効です。]
-
[解決済み】DataFrameオブジェクトが呼び出し可能でないというエラーはどのように解決すればよいですか?
-
[解決済み] Python - 辞書内の値の合計
-
[解決済み] Scipy の疎な行列の乗算
-
[解決済み] Theano隠れ層活性化関数
-
[解決済み] Matplotlib の pyplot 軸フォーマッタ
-
[解決済み] PyMongo 3でServerSelectionTimeoutErrorが発生するのはなぜですか?
-
[解決済み] Errno 9: Pythonソケットのファイルディスクリプタが不正です。