CHAPTER 8 ・ 仕事で使える形にする / Lesson 31
スクリプトにして、引数で動かす
ファイル名や月を、コマンドから渡せる形にする。同じスクリプトを、毎月使い回すための工夫です。
このレッスンが終わったら
「if __name__ == "__main__" と argparse で、コマンドから条件を渡して動かせる」と言える。
こんな場面、ありませんか?
毎月、前の月の売上を集計する仕事があるとします。基礎編のように書くと、コードの中に「何月か」を書き込むことになります。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
正しく動きます。ただ、翌月は month = "2025-10" にコードを書き換えてから動かすことになります。書き換え忘れ、別の行の巻き込み、「この行を直してから動かして」という引き継ぎの説明。毎月の仕事では、こうした小さな事故が起きます。
そこで、コードには手を触れず、動かすときに「何月か」を渡す形にします。コマンド(文字で出す命令)の後ろに、python report.py --month 2025-09 のように値を添える方法です。この、動かすときに渡す値をコマンドライン引数と呼びます。
引数で渡す形にしてみる
コードを、スクリプト(そのまま実行できるPythonファイル)の型に整えます。定数 → 関数 → main() → 最後に if __name__ == "__main__": の順に並べ、月はargparse(コマンドの引数を読み取る標準の道具)で受け取ります。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
最後の行の 2025-09 を 2025-08 に変えて、もう一度動かしてみてください。ほかのコードに触れずに、別の月の結果が出ます。
仕組みを読む
コマンドで打った文字は、次のように、Pythonの中へ運ばれます。
- コマンドpython report.py --month 2025-09
- sys.argv空白で区切ったリスト
- argparse名前と型を確かめて読み取る
- argsargs.month で取り出せる
- main()その月で集計する
parser引数の受付係.add_argument(受け付ける引数を1つ足す"--month"コマンドで打つ名前required=True必ず指定するhelp="集計する月"ヘルプに出す説明)足し終わりdef main(argv=None):main を定義する。argv が None のときは、コマンドの文字を読む parser = argparse.ArgumentParser(prog="report.py", ...)引数の受付係を作る。プログラム名と説明を渡す parser.add_argument("--month", required=True, ...)「--month」を受け付ける。必須にする args = parser.parse_args(argv)受付係に読み取らせて、結果を args に入れる ... args.month ...--month で渡された値を取り出して使うif __name__ == "__main__":このファイルを直接実行したときだけ、次の行を動かす日本語にすると
受け取った args の中身と、自動で作られるヘルプを見てみましょう。--dry-run(「実際の処理はせず、何をするかだけ表示する」ための印。Lesson 29)も足してあります。
▶ 実行を押すと、ここに結果が出ます
--dry-run は値を取らず、書いたかどうかだけを False / True で表します。名前の中の - は、Pythonの中では _ に変わります(args.dry_run)。ヘルプは、自分のパソコンで python report.py -h と打つと表示されます。あとから使う人への説明書になるので、help= は丁寧に書きましょう。
変えて、試す
① 間違った渡し方を、はじく。 月は 2025-09 の形で渡してほしいのに、2025-9 と打たれることがあります。値を受け取る時点で確かめ、違えば、理由つきで止めます。
▶ 実行を押すと、ここに結果が出ます
間違った渡し方をすると、argparse は使い方と理由を表示して、プログラムを終了します(終了コード 2)。ここでは try / except SystemExit で受け止めて、続きを動かしています。自分のパソコンでは、そのまま終了して大丈夫です。
② 設定を、ファイルに出す。 ファイル名や上位の社数のような「ときどき変えたい値」をコードに埋め込むと、直すたびにコードを触ることになります。設定ファイル(config.json)に出して、コードは読むだけにします。
▶ 実行を押すと、ここに結果が出ます
値の強さは、コマンドで指定した値 → config.json → プログラム内の初期値の順です。ふだんは設定ファイルに任せ、その月だけ変えたいときに、コマンドで上書きできます。設定ファイルがないときの備え(FileNotFoundError)は、Lesson 09 の try / except で書けます。
自分で書く
お題① --top を足してください。数として受け取り、書かなかったときは 3 にします。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
parser.add_argument("--top", type=int, default=3) の形です。type=int があるので、5 が数として扱われ、2倍すると 10 になります。
答えの例を見る
import argparse
parser = argparse.ArgumentParser(prog="report.py")
parser.add_argument("--month", required=True)
parser.add_argument("--top", type=int, default=3)
args = parser.parse_args(["--month", "2025-09", "--top", "5"])
print(args.month, args.top * 2)
print(parser.parse_args(["--month", "2025-10"]).top)お題② --dry-run を足してください。指定したときは、「集計しません」と表示します。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
parser.add_argument("--dry-run", action="store_true") の1行です。値を取らない印には、action="store_true" を使います。
答えの例を見る
import argparse
parser = argparse.ArgumentParser(prog="report.py")
parser.add_argument("--month", required=True)
parser.add_argument("--dry-run", action="store_true")
for argv in (["--month", "2025-08", "--dry-run"], ["--month", "2025-08"]):
args = parser.parse_args(argv)
if args.dry_run:
print(args.month, "は試し実行です。集計しません")
else:
print(args.month, "を集計します")お題③ --dept を足してください。選べる値は「営業」と「企画」だけ、書かなかったときは「営業」にします。sales.csv の、その部署の売上合計を表示します。
この欄では、サンプルファイルが使えます。実行のたびに、ファイルは最初の状態に戻ります。
▶ 実行を押すと、ここに結果が出ます
ヒントを見る
parser.add_argument("--dept", choices=["営業", "企画"], default="営業") の形です。choices にない値を渡すと、argparse が止めてくれます。
答えの例を見る
import argparse
import csv
parser = argparse.ArgumentParser(prog="report.py")
parser.add_argument("--dept", choices=["営業", "企画"], default="営業")
with open("sales.csv", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
for argv in ([], ["--dept", "企画"]):
args = parser.parse_args(argv)
total = sum(int(r["売上"]) for r in rows if r["部署"] == args.dept)
print(args.dept, f"{total:,}")仕事ならどう使う?
理解チェック「python report.py --month 2025-09 --dry-run」と打ったとき、args の中身は?(--month は値を1つ取る引数、--dry-run は store_true の印として足してある)
理解チェックファイル名や上位の社数を config.json に出す、いちばんの利点は?