Pythonのargparseモジュールを使うと、コマンドライン引数を簡単に解析でき、ユーザーフレンドリーなCLIツールを作成できます。この記事では、基本的な使い方から高度な機能まで解説します。
コマンドライン引数解析方法の比較
| 方法 | 用途 | 標準ライブラリ | 機能 |
|---|---|---|---|
sys.argv | シンプルな引数取得 | ○ | 最小限 |
argparse | 一般的なCLIツール | ○ | 豊富 |
click | 高度なCLIツール | × | 非常に豊富 |
typer | 型ヒントベースCLI | × | モダン |
基本的な使い方
シンプルな例
import argparse
# パーサーの作成
parser = argparse.ArgumentParser(
description="ファイル処理ツール",
epilog="例: python tool.py input.txt -o output.txt"
)
# 位置引数(必須)
parser.add_argument('filename', help="処理するファイル名")
# オプション引数
parser.add_argument('-o', '--output', help="出力ファイル名")
parser.add_argument('-v', '--verbose', action='store_true', help="詳細表示")
# 引数の解析
args = parser.parse_args()
print(f"入力ファイル: {args.filename}")
print(f"出力ファイル: {args.output}")
print(f"詳細モード: {args.verbose}")
実行例:
$ python tool.py data.txt -o result.txt -v
入力ファイル: data.txt
出力ファイル: result.txt
詳細モード: True
引数の種類
位置引数(必須引数)
import argparse
parser = argparse.ArgumentParser()
# 単一の位置引数
parser.add_argument('source', help="コピー元ファイル")
parser.add_argument('dest', help="コピー先ファイル")
args = parser.parse_args()
# 使用例: python copy.py file1.txt file2.txt
オプション引数
import argparse
parser = argparse.ArgumentParser()
# 短縮形と完全形
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('-c', '--count', type=int, default=1)
parser.add_argument('--name', type=str, required=True) # 必須オプション
args = parser.parse_args()
引数の型と検証
基本的な型
import argparse
parser = argparse.ArgumentParser()
# 整数
parser.add_argument('--port', type=int, default=8080)
# 浮動小数点
parser.add_argument('--rate', type=float, default=0.5)
# 文字列(デフォルト)
parser.add_argument('--name', type=str)
# ファイル(自動で開く)
parser.add_argument('--input', type=argparse.FileType('r'))
parser.add_argument('--output', type=argparse.FileType('w'))
args = parser.parse_args()
選択肢の制限
import argparse
parser = argparse.ArgumentParser()
# 選択肢を指定
parser.add_argument(
'--level',
choices=['debug', 'info', 'warning', 'error'],
default='info',
help="ログレベル"
)
parser.add_argument(
'--format',
choices=['json', 'csv', 'xml'],
required=True,
help="出力フォーマット"
)
args = parser.parse_args()
カスタム型と検証
import argparse
def positive_int(value):
"""正の整数のみ受け付ける"""
ivalue = int(value)
if ivalue <= 0:
raise argparse.ArgumentTypeError(f"{value} は正の整数ではありません")
return ivalue
def valid_percentage(value):
"""0-100の範囲のみ受け付ける"""
fvalue = float(value)
if not 0 <= fvalue <= 100:
raise argparse.ArgumentTypeError(f"{value} は0-100の範囲外です")
return fvalue
parser = argparse.ArgumentParser()
parser.add_argument('--threads', type=positive_int, default=4)
parser.add_argument('--quality', type=valid_percentage, default=80)
args = parser.parse_args()
アクション
import argparse
parser = argparse.ArgumentParser()
# store(デフォルト): 値を保存
parser.add_argument('--name', action='store')
# store_true / store_false: フラグ
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('--no-cache', action='store_true')
# store_const: 固定値を保存
parser.add_argument('--debug', action='store_const', const=10)
# append: リストに追加
parser.add_argument('--include', action='append')
# 使用例: --include foo --include bar → ['foo', 'bar']
# count: 回数をカウント
parser.add_argument('-v', action='count', default=0)
# 使用例: -vvv → 3
# version: バージョン表示
parser.add_argument('--version', action='version', version='%(prog)s 1.0.0')
args = parser.parse_args()
複数の値を受け取る
import argparse
parser = argparse.ArgumentParser()
# 固定数の引数
parser.add_argument('--point', nargs=2, type=float, metavar=('X', 'Y'))
# 使用例: --point 10.5 20.3
# 1つ以上の引数
parser.add_argument('files', nargs='+', help="処理するファイル")
# 使用例: file1.txt file2.txt file3.txt
# 0個以上の引数
parser.add_argument('--tags', nargs='*', default=[])
# オプショナル(0または1)
parser.add_argument('--config', nargs='?', const='config.yaml', default=None)
# --config → 'config.yaml'
# --config custom.yaml → 'custom.yaml'
# (指定なし) → None
args = parser.parse_args()
排他グループ
import argparse
parser = argparse.ArgumentParser()
# 排他的なオプション(どちらか一方のみ指定可能)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--json', action='store_true', help="JSON形式で出力")
group.add_argument('--csv', action='store_true', help="CSV形式で出力")
group.add_argument('--xml', action='store_true', help="XML形式で出力")
args = parser.parse_args()
if args.json:
print("JSON出力")
elif args.csv:
print("CSV出力")
elif args.xml:
print("XML出力")
サブコマンド
GitやDockerのようなサブコマンド構造を実装できます。
import argparse
def cmd_init(args):
print(f"プロジェクト '{args.name}' を初期化します")
def cmd_build(args):
print(f"ビルド中... (verbose={args.verbose})")
def cmd_deploy(args):
print(f"'{args.target}' 環境にデプロイします")
# メインパーサー
parser = argparse.ArgumentParser(
prog='mytool',
description='プロジェクト管理ツール'
)
subparsers = parser.add_subparsers(dest='command', help='利用可能なコマンド')
# init サブコマンド
parser_init = subparsers.add_parser('init', help='新しいプロジェクトを作成')
parser_init.add_argument('name', help='プロジェクト名')
parser_init.set_defaults(func=cmd_init)
# build サブコマンド
parser_build = subparsers.add_parser('build', help='プロジェクトをビルド')
parser_build.add_argument('-v', '--verbose', action='store_true')
parser_build.set_defaults(func=cmd_build)
# deploy サブコマンド
parser_deploy = subparsers.add_parser('deploy', help='デプロイを実行')
parser_deploy.add_argument('target', choices=['dev', 'staging', 'prod'])
parser_deploy.set_defaults(func=cmd_deploy)
# 解析と実行
args = parser.parse_args()
if args.command:
args.func(args)
else:
parser.print_help()
実行例:
$ python mytool.py init myproject
プロジェクト 'myproject' を初期化します
$ python mytool.py build -v
ビルド中... (verbose=True)
$ python mytool.py deploy prod
'prod' 環境にデプロイします
実践的な例
ファイル処理ツール
#!/usr/bin/env python3
import argparse
import sys
from pathlib import Path
def process_file(input_path: Path, output_path: Path, uppercase: bool):
"""ファイルを処理する"""
content = input_path.read_text(encoding='utf-8')
if uppercase:
content = content.upper()
output_path.write_text(content, encoding='utf-8')
print(f"処理完了: {input_path} → {output_path}")
def main():
parser = argparse.ArgumentParser(
description='テキストファイル処理ツール',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog='''
使用例:
%(prog)s input.txt -o output.txt
%(prog)s input.txt --uppercase -o output.txt
'''
)
parser.add_argument('input', type=Path, help='入力ファイル')
parser.add_argument('-o', '--output', type=Path, required=True, help='出力ファイル')
parser.add_argument('-u', '--uppercase', action='store_true', help='大文字に変換')
parser.add_argument('--version', action='version', version='%(prog)s 1.0.0')
args = parser.parse_args()
# 入力ファイルの存在確認
if not args.input.exists():
print(f"エラー: ファイルが見つかりません: {args.input}", file=sys.stderr)
sys.exit(1)
process_file(args.input, args.output, args.uppercase)
if __name__ == '__main__':
main()
設定ファイルとの組み合わせ
import argparse
import json
from pathlib import Path
def load_config(config_path: Path) -> dict:
"""設定ファイルを読み込む"""
if config_path.exists():
return json.loads(config_path.read_text())
return {}
def main():
# 設定ファイルのデフォルト値
config = load_config(Path('config.json'))
parser = argparse.ArgumentParser()
parser.add_argument('--host', default=config.get('host', 'localhost'))
parser.add_argument('--port', type=int, default=config.get('port', 8080))
parser.add_argument('--debug', action='store_true', default=config.get('debug', False))
args = parser.parse_args()
print(f"サーバー起動: {args.host}:{args.port} (debug={args.debug})")
if __name__ == '__main__':
main()
ヘルプメッセージのカスタマイズ
import argparse
parser = argparse.ArgumentParser(
prog='myapp',
description='アプリケーションの説明',
epilog='詳細は https://example.com を参照',
formatter_class=argparse.ArgumentDefaultsHelpFormatter # デフォルト値を表示
)
parser.add_argument(
'--config',
metavar='FILE', # ヘルプでの表示名
help='設定ファイルのパス'
)
parser.add_argument(
'--level',
choices=['low', 'medium', 'high'],
default='medium',
help='処理レベル'
)
args = parser.parse_args()
ヘルプ出力:
$ python myapp.py -h
usage: myapp [-h] [--config FILE] [--level {low,medium,high}]
アプリケーションの説明
optional arguments:
-h, --help show this help message and exit
--config FILE 設定ファイルのパス (default: None)
--level {low,medium,high}
処理レベル (default: medium)
詳細は https://example.com を参照
まとめ
| 機能 | 方法 |
|---|---|
| 位置引数 | add_argument('name') |
| オプション引数 | add_argument('--name') |
| 短縮形 | add_argument('-n', '--name') |
| 型指定 | type=int / type=float |
| デフォルト値 | default=value |
| 選択肢制限 | choices=['a', 'b', 'c'] |
| フラグ | action='store_true' |
| 複数値 | nargs='+' / nargs='*' |
| 排他グループ | add_mutually_exclusive_group() |
| サブコマンド | add_subparsers() |
argparseを使えば、プロフェッショナルなコマンドラインツールを簡単に作成できます。