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期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?