PythonでWebプログラミングの基礎を学習するというテーマで書いています。前回はCGIでの例外処理というテーマで書きました。今回は以下の内容の続きの内容です。実際に動作させてみる場合等で必要な場合は以下を参照して下さい。
PythonでWebプログラミングの基礎(その7)CGIでパラメータを保存する
今回はこの時のプログラムを関数分割してみるという内容です。短いプログラムなので関数分割するほどでもないのですが、これで実際にやってみます。
CGIプログラムの処理の流れ
今回のCGIプログラムの流れとしては以下です。
ユーザ登録のような画面が表示されます。
ここで何でもいいので登録情報を入力します。登録ボタンで今回のCGIプログラムが呼び出されます。
関数分割する前のプログラム
関数分割する前のプログラムは以下です。
#!/usr/bin/env python3 htmlText = '''Content-type: text/html; charset=UTF-8 <html> <head> <title>CGIパラメータの取得</title> <link rel="stylesheet" href="../style.css"> </head> <body> <header class="header"> <p>取得したパラメータ</p> </header> <div class="content"> <p>%sさん、よろしくお願いします。</p> </div> </body> </html> ''' import cgi form = cgi.FieldStorage() name = form.getvalue('username','') loginname = form.getvalue('handlename','') password = form.getvalue('passwd','') email = form.getvalue('mail','') line = '%s,%s,%s,%s\n' file = open('member.txt','a') file.write(line % (name,loginname,password,email)) file.close() print(htmlText % name)
関数に分割する
上記のプログラムは以下のような処理の流れです。
POSTされたパラメータの各項目を取得する
各項目を1行のカンマ区切り文字列にする
1行になったデータをファイルへ追加書きする
処理結果を表示する
これをどのように関数分割するかですが、その前にPythonでの関数の基本的な内容については以下で書きました。
Pythonでの関数定義と関数呼び出し
つまり、ここでは意味のあるまとまった処理としての関数に分割するということです。
以下のように分割しました。これが唯一の正しい答えということではなく一つの例や過程として見てください。(※グローバル変数を使うのは関数(モジュール)の独立性を高くするという意味では良くないとされています。但し、ここではまずは処理を分割するというぐらいの観点で以下のように分割しました。)
分割した処理では入力チェックとしてパラメータが未入力の場合にエラーメッセージを表示するように処理を追加しました。このようにまとまった処理(関数)の結果で後続の処理を(分かりやすく)分岐することが出来ますという意味でこの処理を追加しました。
#!/usr/bin/env python3 ###正常処理時のHTML htmlText = '''Content-type: text/html; charset=UTF-8 <html> <head> <title>CGIパラメータの取得</title> <link rel="stylesheet" href="../style.css"> </head> <body> <header class="header"> <p>保存が完了しました。</p> </header> <div class="content"> <p>%sさん、よろしくお願いします。</p> </div> </body> </html> ''' ###エラー処理時のHTML htmlTextErr = '''Content-type: text/html; charset=UTF-8 <html> <head> <title>CGIパラメータの取得</title> <link rel="stylesheet" href="../style.css"> </head> <body> <header class="header"> <p>入力チェックエラーです。</p> </header> <div class="content"> <p>%sを入力して下さい。</p> <p><a href="http://localhost:8000/">入力ページへ戻る</a></p> </div> </body> </html> ''' ###ここから処理 import cgi ##CGIパラメータ変数の定義 name = '' loginname = '' password = '' email = '' ## CGIパラメータを取得する def getParameter(): #設定するためにグローバル変数として定義 global name global loginname global password global email form = cgi.FieldStorage() name = form.getvalue('username','') loginname = form.getvalue('handlename','') password = form.getvalue('passwd','') email = form.getvalue('mail','') ## 未入力チェック def checkParameter(): if not name: print(htmlTextErr % 'お名前') return False if not loginname: print(htmlTextErr % 'ログイン名') return False if not password: print(htmlTextErr % 'パスワード') return False if not email: print(htmlTextErr % 'メールアドレス') return False return True ## ファイルへの保存を実行する def saveExec(): line = '%s,%s,%s,%s\n' file = open('member.txt','a') file.write(line % (name,loginname,password,email)) file.close() print(htmlText % name) ## メイン関数 def main(): #各関数の呼び出し getParameter() if(checkParameter() == False): return; saveExec() if __name__ == "__main__": main()
分割した関数
getParameter(): CGIパラメータを取得する
checkParameter(): 各CGIパラメータをチェックして未入力の場合はエラーメッセージを表示して処理を中断する
saveExec(): 有効なCGIパラメータを保存する
checkParameter()関数で未入力があった場合は以下のような表示になります。
PAD図でのmain関数の流れ
PAD図については以下で書きました。
フローチャートと構造化チャート
今回のmain関数での各関数の呼び出しと分岐をPAD図で書いてみました。
要点は以下です。
関数を処理の順番に呼び出している
関数の処理の結果で分岐が必要な場合は分岐している
各CGIパラメータはグローバル変数で保持している(関数内で変数を更新する場合はglobalで宣言している)
各関数の処理詳細が必要な場合は関数分割前のプログラムについて書いた以下を参照して下さい。
PythonでWebプログラミングの基礎(その7)CGIでパラメータを保存する
(補足1)Pythonでのグローバル変数
ここでは何となくグローバル変数ですということで使用しましたが使い方を間違えると全く意図しない結果になります。変数のスコープという考え方が重要になってきます。必要な場合は以下等を参照して下さい。
打倒、Pythonのグローバル宣言
(補足2)モジュールの結合度
モジュール(関数)の結合度という考え方があります。結合度が低くなるようにすることで、モジュールの独立性を高くすることが出来ます。独立性が高いということは再利用性が高いということです。グローバル変数も関わってきて重量なテーマですが、簡単には書けません。興味を持たれた場合は以下等を参照して下さい。
モジュール間結合度についてPythonのコード付きでまとめてみる
今回はここまでです。また書きたいと思います。