はじめに
pythonで書かれたバッチジョブにて、ジョブ途中停止の状況によりリランする位置を変えたいという要望がありました。
本記事ではその方法について考えていきたいと思います。
お断り
ここに書くことは基本的にバッドノウハウだと思います。
pythonでできないこと
gotoがない
今どきのプログラミング言語では存在するほうが珍しいgoto構文ですが、pythonにも当然存在しないようです。
ただ、検索すると冗談のようなgotoモジュールが存在します。実際冗談なので使用してはいけないでしょう。
switchもない
swithがあれば以下の様に記載できるでしょう。
void job(int stepNo){
switch stepNo{
case 0:
// step0の処理を実行
case 1:
// step1の処理を実行
case 2:
// step2の処理を実行
case 3:
// step3の処理を実行
default:
// 有効なstepNoが存在しない場合は何もしないが、defalutを空にはできないので何かしらのダミー処理を入れる
}
というようにbreak文のないswitch構文であれば、比較的簡単にリランの実行位置を外部から与えることができます。
しかしpythonにはswitch構文が存在しません。if-elseで全部代替できるからということですが、breakを使わないswitch構文はその限りではないでしょう、と声を大にして言いたい(言うとは言っていない)。
代替手段検討
その1 リスト形式
# stepNoは外部から与えられたリラン位置番号
if stepNo in [1,2,3]:
# step1の処理
if stepNo in [2,3]:
# step2の処理
if stepNo in [3]:
# step3の処理
上記の様にリラン番号がリストに入っているかどうかでそのブロックを実行するかどうか判断できるかと思います。
ただこの方法はプログラム上のリラン番号がコードから分かりにくいのでstepごとのコメントは必須となるでしょうか。
リテラルでin以降を書きたくない場合はこうなりますでしょうか。
# stepNoは外部から与えられたリラン位置番号
rerunList = [1,2,3]
if stepNo in rerunList:
# step1の処理
rerunList.pop(0)
if stepNo in rerunList:
# step2の処理
rerunList.pop(0)
if stepNo in rerunList:
# step3の処理
rerunList.pop(0)
stepNoの大小関係で判断
外部から与えるstepNoが実行ステップ以上であればifブロックを実行する方法も考えられます。
# stepNoは外部から与えられたリラン位置番号
if stepNo >= 1:
# step1の処理
if stepNo >= 2:
# step2の処理
if stepNo >= 3:
# step3の処理
こちらのほうが汎用的でしょうか。
コード上でどのステップかも追うことができます。
リテラルをそのまま埋め込むのはどうかとは思いますが。
また、stepを10刻みとかにして保守時に新しいstepを挿入することも比較的簡単かもしれません。
昔のBASICの行番号みたいに。
wip
他の方法を思いついたらまた追記したいと思います。