- Python
Python argparse 使い方|引数一覧表とCLI雛形・3.14対応
argparseとは、Pythonのスクリプトに渡すコマンドライン引数を解析し、型変換・必須チェック・ヘルプ表示・エラー表示までを自動で行う標準ライブラリです。 ArgumentParser を作り、add_argument() で引数を定義し、parse_args() で受け取るのが基本の3ステップです。
この記事では、add_argument() の引数を一覧表で整理したうえで、すべて「コード → 実行したコマンド → 出力」の順で確認しています。検証は Python 3.14.7(3.11・3.13 との違いは明記)。サブコマンド、環境変数からの既定値、エラー時の終了コード、3.14 で加わった打ち間違いの候補表示(suggest_on_error)まで扱い、最後にそのまま使えるCLI雛形を載せました。出力は NO_COLOR=1 で色を消して取得しています。
argparse の早見表
| やりたいこと | 書き方 |
|---|---|
| 必須の位置引数 | add_argument("path") |
| 値を取るオプション | add_argument("-n", "--limit", type=int, default=10) |
| フラグ(付けたらTrue) | action="store_true" |
--xxx / --no-xxx の両方 |
action=argparse.BooleanOptionalAction |
| 複数回指定でリスト | action="append" |
-vvv で回数 |
action="count", default=0 |
| 値を複数受け取る | nargs="+"(1個以上)/"*"(0個以上)/"?"(0か1)/2(ちょうど2) |
| 選択肢を限定 | choices=["csv", "json"] |
| オプションを必須に | required=True |
| ファイルパスで受け取る | type=Path |
| 独自の型チェック | type=関数(argparse.ArgumentTypeError を送出) |
| 同時指定を禁止 | add_mutually_exclusive_group() |
| サブコマンド | add_subparsers() + set_defaults(func=関数) |
| 環境変数を既定値に | default=os.environ.get("X") |
| バージョン表示 | action="version", version="%(prog)s 1.0" |
| 打ち間違いの候補表示 | ArgumentParser(suggest_on_error=True)(3.14〜) |
| テストから呼ぶ | parser.parse_args(["--limit", "3"]) |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Python argparse 使い方|引数一覧表とCLI雛形・3.14対応」
1. 最小の例と -h の出力
# greet.py
import argparse
parser = argparse.ArgumentParser(description="注文CSVを集計します")
parser.add_argument("path", help="入力ファイル") # 位置引数(必須)
parser.add_argument("-n", "--limit", type=int, default=10, help="表示件数(既定: %(default)s)")
parser.add_argument("-v", "--verbose", action="store_true", help="詳しく表示")
args = parser.parse_args()
print(args)
print(args.path, args.limit, args.verbose)
$ python greet.py orders.csv
Namespace(path='orders.csv', limit=10, verbose=False)
orders.csv 10 False
$ python greet.py orders.csv -n 3 -v
Namespace(path='orders.csv', limit=3, verbose=True)
orders.csv 3 True
$ python greet.py orders.csv --limit=5
Namespace(path='orders.csv', limit=5, verbose=False)
orders.csv 5 False
- で始まらない引数は位置引数(必須)、- で始まるものはオプション(省略可)です。--limit は属性名 args.limit になり、--dry-run のようなハイフンは args.dry_run とアンダースコアに変わります。%(default)s はヘルプの中で既定値に置き換わります。
-h の出力は自動で作られます。
$ python greet.py -h
usage: greet.py [-h] [-n LIMIT] [-v] path
注文CSVを集計します
positional arguments:
path 入力ファイル
options:
-h, --help show this help message and exit
-n, --limit LIMIT 表示件数(既定: 10)
-v, --verbose 詳しく表示
3.13 から、短い名前と長い名前の表示が -n, --limit LIMIT とまとまりました。 3.11 では -n LIMIT, --limit LIMIT と2回表示され、説明が次の行に回ります。
2. エラー時の出力と終了コード(2)
引数が正しくないと、argparse は使い方(usage)とエラーを標準エラーに出し、終了コード2で終了します。 自分で if を書かなくても、必須チェックと型チェックが行われます。
$ python greet.py
usage: greet.py [-h] [-n LIMIT] [-v] path
greet.py: error: the following arguments are required: path
exit=2
$ python greet.py a.csv -n abc
usage: greet.py [-h] [-n LIMIT] [-v] path
greet.py: error: argument -n/--limit: invalid int value: 'abc'
exit=2
$ python greet.py a.csv --foo
usage: greet.py [-h] [-n LIMIT] [-v] path
greet.py: error: unrecognized arguments: --foo
exit=2
長いオプションは、他と区別できれば途中まででも受け付けます(--verbos → --verbose、--lim 3 → --limit 3 として動きました)。意図しない省略を受け付けたくないときは ArgumentParser(allow_abbrev=False) にします。
| 終了コード | 意味 |
|---|---|
| 0 | 正常終了(-h や --version も0) |
| 2 | 引数のエラー(argparse が自動で終了) |
| 1 など | プログラム側で決める(雛形では処理の失敗を1にしています) |
3. add_argument の引数一覧
| 引数 | 役割 | 例 |
|---|---|---|
| name / flags | 位置引数の名前、またはオプション名 | "path" / "-n", "--limit" |
action |
値の扱い方(下の表) | "store_true" |
nargs |
受け取る値の個数 | "?" "*" "+" 2 |
type |
文字列を変換する関数 | int float Path date.fromisoformat |
choices |
許可する値 | ["csv", "json"] |
default |
省略時の値 | 10 |
required |
オプションを必須にする | True |
dest |
保存先の属性名 | dest="key" |
metavar |
ヘルプでの値の表示名 | "YYYY-MM-DD" |
help |
ヘルプの説明(argparse.SUPPRESS で非表示) |
"入力ファイル" |
const |
store_const などで保存する固定値 |
const="fast" |
4. action の種類を実行して比べる
# actions.py
import argparse
p = argparse.ArgumentParser(prog="actions")
p.add_argument("--name") # store(既定)
p.add_argument("--dry-run", action="store_true") # 付けると True
p.add_argument("--no-color", dest="color", action="store_false")# 付けると False
p.add_argument("--fast", dest="mode", action="store_const", const="fast", default="normal")
p.add_argument("--tag", action="append") # 複数回 → リスト
p.add_argument("--ids", action="extend", nargs="+", type=int) # まとめて追加
p.add_argument("-v", action="count", default=0) # 回数を数える
p.add_argument("--cache", action=argparse.BooleanOptionalAction, default=True)
p.add_argument("--version", action="version", version="%(prog)s 1.2.0")
for argv in ([],
["--name", "ペン", "--dry-run", "--no-color", "--fast"],
["--tag", "急ぎ", "--tag", "ギフト", "--ids", "1", "2", "--ids", "3"],
["-vvv", "--no-cache"]):
print(argv, "->", vars(p.parse_args(argv)))
p.parse_args(["--version"])
[] -> {'name': None, 'dry_run': False, 'color': True, 'mode': 'normal', 'tag': None, 'ids': None, 'v': 0, 'cache': True}
['--name', 'ペン', '--dry-run', '--no-color', '--fast'] -> {'name': 'ペン', 'dry_run': True, 'color': False, 'mode': 'fast', 'tag': None, 'ids': None, 'v': 0, 'cache': True}
['--tag', '急ぎ', '--tag', 'ギフト', '--ids', '1', '2', '--ids', '3'] -> {'name': None, 'dry_run': False, 'color': True, 'mode': 'normal', 'tag': ['急ぎ', 'ギフト'], 'ids': [1, 2, 3], 'v': 0, 'cache': True}
['-vvv', '--no-cache'] -> {'name': None, 'dry_run': False, 'color': True, 'mode': 'normal', 'tag': None, 'ids': None, 'v': 3, 'cache': False}
actions 1.2.0
parse_args() にリストを渡すと、コマンドラインの代わりにその値で解析します。 テストで便利です。
| action | 指定したとき | 省略したとき |
|---|---|---|
store(既定) |
値を保存 | None |
store_true / store_false |
True / False |
False / True |
store_const |
const の値 |
default(未指定なら None) |
append |
指定ごとにリストへ追加 | None |
append_const |
const をリストへ追加 |
None |
extend |
複数の値をまとめてリストへ追加 | None |
count |
指定回数 | default(0 を指定しておく) |
BooleanOptionalAction |
--cache で True、--no-cache で False |
default |
help / version |
表示して終了(終了コード0) | ― |
append と count は default を付けないと、省略時が None になります(count は default=0 が定番)。
5. nargs で値の個数を決める
# nargs.py
import argparse
p = argparse.ArgumentParser(prog="nargs")
p.add_argument("src", nargs="+") # 1個以上
p.add_argument("dst", nargs="?", default="out/") # 0か1個
p.add_argument("--size", nargs=2, type=int, metavar=("W", "H")) # ちょうど2個
p.add_argument("--exclude", nargs="*", default=[]) # 0個以上
for argv in (["a.csv"], ["a.csv", "b.csv", "dist/"], ["a.csv", "--size", "800", "600", "--exclude"],
["a.csv", "--exclude", "x", "y"]):
print(argv, "->", vars(p.parse_args(argv)))
p.print_usage()
p.parse_args(["a.csv", "--size", "800"])
['a.csv'] -> {'src': ['a.csv'], 'dst': 'out/', 'size': None, 'exclude': []}
['a.csv', 'b.csv', 'dist/'] -> {'src': ['a.csv', 'b.csv', 'dist/'], 'dst': 'out/', 'size': None, 'exclude': []}
['a.csv', '--size', '800', '600', '--exclude'] -> {'src': ['a.csv'], 'dst': 'out/', 'size': [800, 600], 'exclude': []}
['a.csv', '--exclude', 'x', 'y'] -> {'src': ['a.csv'], 'dst': 'out/', 'size': None, 'exclude': ['x', 'y']}
usage: nargs [-h] [--size W H] [--exclude [EXCLUDE ...]] src [src ...] [dst]
usage: nargs [-h] [--size W H] [--exclude [EXCLUDE ...]] src [src ...] [dst]
nargs: error: argument --size: expected 2 arguments
2つ目の結果に注目してください。dist/ は dst ではなく src に入りました。 nargs="+" の位置引数はできるだけ多く取るため、後ろの nargs="?" には何も残りません。出力先はオプション(-o/--output)にすると、この取り違えが起きません。metavar にタプルを渡すと、--size W H のように値ごとの名前を表示できます。
| nargs | 個数 | 値の型 |
|---|---|---|
| なし | 1個 | 単一の値 |
N(整数) |
ちょうどN個 | リスト |
"?" |
0か1個 | 単一の値(なければ default) |
"*" |
0個以上 | リスト |
"+" |
1個以上 | リスト |
6. type・choices・required・dest・metavar と環境変数の既定値
# export.py
import argparse
import os
from datetime import date
from pathlib import Path
def positive_int(text: str) -> int:
n = int(text)
if n <= 0:
raise argparse.ArgumentTypeError(f"1以上を指定してください: {text}")
return n
p = argparse.ArgumentParser(prog="export", suggest_on_error=True)
p.add_argument("input", type=Path, help="入力ファイル")
p.add_argument("--since", type=date.fromisoformat, metavar="YYYY-MM-DD")
p.add_argument("--workers", type=positive_int, default=2)
p.add_argument("--format", choices=["csv", "json"], default="csv")
env_key = os.environ.get("EXPORT_API_KEY")
p.add_argument("--api-key", dest="key", default=env_key, required=env_key is None,
help="未指定なら環境変数 EXPORT_API_KEY を使う")
p.add_argument("--region", default=os.environ.get("EXPORT_REGION", "tokyo"),
help="既定値は環境変数 EXPORT_REGION(未設定なら %(default)s)")
args = p.parse_args()
print(repr(args.input), args.input.suffix, repr(args.since), args.workers, args.format, args.key, args.region)
$ python export.py data/orders.csv --since 2026-09-01 --api-key K1
PosixPath('data/orders.csv') .csv datetime.date(2026, 9, 1) 2 csv K1 tokyo
$ EXPORT_API_KEY=K9 EXPORT_REGION=osaka python export.py data/orders.csv
PosixPath('data/orders.csv') .csv None 2 csv K9 osaka
$ python export.py a.csv --since 2026/09/01 --api-key K1
export: error: argument --since: invalid fromisoformat value: '2026/09/01'
$ python export.py a.csv --workers 0 --api-key K1
export: error: argument --workers: 1以上を指定してください: 0
$ python export.py a.csv --format jsn --api-key K1
export: error: argument --format: invalid choice: 'jsn', maybe you meant 'json'? (choose from 'csv', 'json')
$ python export.py a.csv
export: error: the following arguments are required: --api-key
(エラーの前の usage 行は省略。終了コードはいずれも2)
type=Pathで受け取ると、そのまま.suffixや.exists()が使えます。 3.14 ではargparse.FileTypeを使うとPendingDeprecationWarning: FileType is deprecated. Simply open files after parsing arguments.が出るため、ファイルはPathで受け取り、自分でopen()するのがよいでしょう。typeには「文字列を受け取って値を返す関数」なら何でも渡せます。ArgumentTypeErrorを送出すると、そのメッセージがエラーに出ます。- 環境変数は
default=os.environ.get(...)で既定値にし、required=env_key is Noneとすると「環境変数もオプションもないときだけ必須」にできます。required=Trueとdefaultを併用すると、既定値があってもオプションを省略できません。 choicesの打ち間違いにmaybe you meant 'json'?と出ているのが、3.14 のsuggest_on_error=Trueの効果です(8章)。
よくある間違いが type=bool です。 bool("False") は True になるため、次のようになります。
p = argparse.ArgumentParser()
p.add_argument("--debug", type=bool, default=False)
print(p.parse_args(["--debug", "False"]))
print(p.parse_args(["--debug", ""]))
Namespace(debug=True)
Namespace(debug=False)
真偽値は store_true か BooleanOptionalAction を使います。
7. 同時指定を禁止する(相互排他グループ)
import argparse
p = argparse.ArgumentParser(prog="report")
g = p.add_mutually_exclusive_group() # required=True で「どちらか必須」
g.add_argument("-q", "--quiet", action="store_true")
g.add_argument("-v", "--verbose", action="store_true")
print(p.parse_args(["-v"]))
p.parse_args(["-q", "-v"])
Namespace(quiet=False, verbose=True)
usage: report [-h] [-q | -v]
report: error: argument -v/--verbose: not allowed with argument -q/--quiet
usage に [-q | -v] と表示され、どちらか一方しか使えないことが利用者に伝わります。
8. Python 3.14 での変更点
| 変更 | 内容 | 確認結果 |
|---|---|---|
suggest_on_error |
選択肢やサブコマンド名の打ち間違いに候補を表示(既定は False) | invalid choice: 'lst', maybe you meant 'list'? |
| 色付きヘルプ | ヘルプ・エラーが色付きに。color=False か環境変数 NO_COLOR / PYTHON_COLORS で制御 |
本記事は NO_COLOR=1 で取得 |
prog の既定値 |
起動方法を反映 | python -m pkg の usage が 3.14 は python3.14 -m pkg、3.11 は __main__.py |
FileType |
非推奨 | PendingDeprecationWarning を確認。type=Path を使う |
3.13 以前で suggest_on_error=True を渡すと、TypeError: ArgumentParser.__init__() got an unexpected keyword argument 'suggest_on_error' になります(3.11 で確認)。複数バージョンで動かすなら、次の雛形のように sys.version_info で切り替えます。
9. サブコマンドとCLI雛形(そのまま使える完成形)
git add / git commit のようなサブコマンドは add_subparsers() で作り、set_defaults(func=関数) で呼ぶ関数を結び付けます。 次の雛形は、サブコマンド・ログレベル・--dry-run・終了コードを備えたタスク管理CLIです。コマンド名と処理を置き換えれば、そのまま自分のツールになります。
"""タスク管理CLIの雛形(サブコマンド・ログレベル・--dry-run)"""
import argparse
import json
import logging
import sys
from pathlib import Path
log = logging.getLogger("tasks")
DB = Path("tasks.json")
def load() -> list[dict]:
return json.loads(DB.read_text(encoding="utf-8")) if DB.exists() else []
def save(tasks: list[dict], dry_run: bool) -> None:
if dry_run:
log.info("dry-run: 保存しません(%d件)", len(tasks))
return
DB.write_text(json.dumps(tasks, ensure_ascii=False, indent=2), encoding="utf-8")
log.debug("保存しました: %s", DB)
def cmd_add(args: argparse.Namespace) -> int:
tasks = load()
tasks.append({"id": len(tasks) + 1, "title": args.title, "done": False})
save(tasks, args.dry_run)
print(f"追加: {args.title}")
return 0
def cmd_list(args: argparse.Namespace) -> int:
for t in load():
if args.all or not t["done"]:
print(f"{t['id']:>3} [{'x' if t['done'] else ' '}] {t['title']}")
return 0
def cmd_done(args: argparse.Namespace) -> int:
tasks = load()
for t in tasks:
if t["id"] == args.id:
t["done"] = True
save(tasks, args.dry_run)
print(f"完了: {t['title']}")
return 0
log.error("ID %d のタスクはありません", args.id)
return 1
def build_parser() -> argparse.ArgumentParser:
extra = {"suggest_on_error": True} if sys.version_info >= (3, 14) else {}
parser = argparse.ArgumentParser(prog="tasks", description="タスクを管理します", **extra)
parser.add_argument("--log-level", default="WARNING",
choices=["DEBUG", "INFO", "WARNING", "ERROR"])
parser.add_argument("--dry-run", action="store_true", help="保存せずに動作だけ確認")
parser.add_argument("--version", action="version", version="%(prog)s 0.1.0")
sub = parser.add_subparsers(title="コマンド", dest="command", required=True)
p = sub.add_parser("add", help="タスクを追加")
p.add_argument("title")
p.set_defaults(func=cmd_add)
p = sub.add_parser("list", aliases=["ls"], help="タスクを一覧")
p.add_argument("-a", "--all", action="store_true", help="完了済みも表示")
p.set_defaults(func=cmd_list)
p = sub.add_parser("done", help="タスクを完了にする")
p.add_argument("id", type=int)
p.set_defaults(func=cmd_done)
return parser
def main(argv: list[str] | None = None) -> int:
args = build_parser().parse_args(argv)
logging.basicConfig(level=args.log_level, format="%(levelname)s %(message)s")
return args.func(args)
if __name__ == "__main__":
sys.exit(main())
実行結果(Python 3.14.7):
$ python tasks.py -h
usage: tasks [-h] [--log-level {DEBUG,INFO,WARNING,ERROR}] [--dry-run]
[--version]
{add,list,ls,done} ...
タスクを管理します
options:
-h, --help show this help message and exit
--log-level {DEBUG,INFO,WARNING,ERROR}
--dry-run 保存せずに動作だけ確認
--version show program's version number and exit
コマンド:
{add,list,ls,done}
add タスクを追加
list (ls) タスクを一覧
done タスクを完了にする
$ python tasks.py add 備品を発注する
追加: 備品を発注する
$ python tasks.py add 議事録を共有する
追加: 議事録を共有する
$ python tasks.py --dry-run --log-level INFO add 下書き
INFO dry-run: 保存しません(3件)
追加: 下書き
$ python tasks.py done 1
完了: 備品を発注する
$ python tasks.py ls --all
1 [x] 備品を発注する
2 [ ] 議事録を共有する
$ python tasks.py done 9
ERROR ID 9 のタスクはありません
exit=1
$ python tasks.py lst
tasks: error: argument command: invalid choice: 'lst', maybe you meant 'list'? (choose from 'add', 'list', 'ls', 'done')
$ python tasks.py add 下書き --dry-run
tasks: error: unrecognized arguments: --dry-run
雛形のポイント
| ポイント | 理由 |
|---|---|
set_defaults(func=cmd_add) → args.func(args) |
サブコマンドごとの if 分岐が不要になる |
add_subparsers(..., required=True) |
サブコマンドなしで実行すると the following arguments are required: command で終了コード2 |
main(argv=None) が終了コードを返す |
テストから main(["add", "x"]) と呼べ、sys.exit(main()) で終了コードも伝わる |
aliases=["ls"] |
短い別名を付けられる |
--log-level を logging に渡す |
--log-level DEBUG で詳細ログを出せる |
最後の実行結果のとおり、親パーサーのオプション(--dry-run)はサブコマンド名より前に書きます。 後ろにも書けるようにするなら、サブコマンド側にも同じオプションを default=argparse.SUPPRESS で追加します。こうすると --dry-run add x と add x --dry-run のどちらも dry_run=True になりました。parents=[...] で普通に追加すると、前に書いた --dry-run がサブコマンド側の既定値 False で上書きされた(3.14.7 で確認)ので注意します。
10. argparse・click・typer の選び方
| 観点 | argparse | click | typer |
|---|---|---|---|
| 導入 | 標準ライブラリ(不要) | uv add click |
uv add typer |
| 書き方 | add_argument() を並べる |
デコレーター | 型ヒントから自動生成 |
| 向いている場面 | 配布先に追加インストールできない、依存を増やしたくない | コマンドが多い本格的なCLI | 型ヒントで短く書きたい |
単体のスクリプトや社内ツールなら argparse で十分です。サブコマンドが増えてきたら click や typer も検討するとよいでしょう。
よくある質問
Q. オプションを必須にするには?
A. add_argument("--api-key", required=True) です。ただし利用者には「オプション=省略可」と受け取られやすいため、必須の値は位置引数にするのも1つの方法です。
Q. args.dry-run でアクセスできません。
A. オプション名のハイフンはアンダースコアに変わるため args.dry_run です。別の名前にしたいときは dest="名前" を指定します。
Q. Jupyter Notebook で parse_args() がエラーになります。
A. Notebook のカーネルが受け取る引数を解析してしまうためです。parser.parse_args([]) や parser.parse_args(["a.csv", "-n", "3"]) のようにリストを渡して呼びます。
まとめ
ArgumentParser→add_argument()→parse_args()の3ステップで、型変換・必須チェック・ヘルプが自動でそろう- 引数エラーは usage を出して終了コード2。自分の処理の失敗は1などを返す
- 真偽値は
store_true/BooleanOptionalAction。type=boolは"False"も True になる nargs="+"の後ろの"?"は値を取れないことがある。出力先はオプションにする- ファイルは
type=Path、環境変数はdefault=os.environ.get()(3.14 でFileTypeは非推奨) - サブコマンドは
add_subparsers()+set_defaults(func=)、main(argv)にするとテストしやすい - 3.14 は
suggest_on_errorと色付きヘルプが加わり、打ち間違いに候補を出せる
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Python argparse 使い方|引数一覧表とCLI雛形・3.14対応」
株式会社RJCでは、日々の作業を小さなCLIツールにして、使いやすさを仲間と話し合いながら改善しています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。