Python argparse: 10분 안에 CLI 도구 만들기
Source: Dev.to
🎁 무료: AI 출판 체크리스트 — 파이썬으로 7단계
전체 파이프라인: (원하는 금액을 지불하세요, 최소 $9.99)
문제
간단한 스크립트를 작성하고 파일 이름을 하드코딩했지만, 곧바로 바꿔야 할 상황이 생깁니다.
sys.argv를 사용합니다:
import sys
filename = sys.argv[1]
count = int(sys.argv[2])
작동은 하지만, 문제가 생깁니다:
- 인자를 주지 않고 실행 →
IndexError. - 정수를 기대하는 곳에 정수가 아닌 값을 전달 → 크래시.
- 도움말 텍스트도 없고, 검증도 없으며, 기본값도 없습니다.
스크립트를 사용하는 다른 사람은 어떻게 실행해야 하는지 알기 위해 소스 코드를 읽어야 합니다.
왜 argparse인가?
argparse (표준 라이브러리)는 이 모든 문제를 해결합니다.
parse_args() 한 번 호출로 다음을 처리합니다:
sys.argv읽기- 입력 검증
- 도움말 출력 (
--help)
기본 보일러플레이트
import argparse
parser = argparse.ArgumentParser(
description="My CLI tool — does useful things."
)
args = parser.parse_args()
위치 인수
필수이며 이름이 아니라 위치로 식별됩니다:
parser.add_argument("filename", help="Path to the input file")
parser.add_argument("count", help="Number of items to process")
선택적 (플래그) 인자
-- 접두사를 사용합니다; 짧은 별칭은 선택 사항입니다:
parser.add_argument(
"--output", "-o",
help="Output file path",
default="output.txt"
)
parser.add_argument(
"--verbose", "-v",
help="Enable verbose logging",
action="store_true"
)
타입 변환 및 선택
argparse가 변환 및 검증을 수행하도록 합니다:
parser.add_argument(
"--count", type=int, default=10,
help="Number of items"
)
parser.add_argument(
"--rate", type=float, default=1.5,
help="Processing rate"
)
parser.add_argument(
"--format",
choices=["json", "csv", "txt"],
default="json",
help="Output format"
)
사용자가 --count hello를 실행하면, argparse는 깔끔한 오류 메시지를 출력하고 종료합니다—스택 트레이스는 표시되지 않습니다.
nargs와 리스트
| 예시 | 의미 |
|---|---|
parser.add_argument("--title", required=True, help="Article title (required)") | 필수 옵션 인자 |
parser.add_argument("--tags", nargs="+", help="One or more tags") | 하나 이상 값 (+) |
parser.add_argument("--tags", nargs="*", help="Zero or more tags") | 0개 이상 값 (*) |
결과는 직접 반복(iterate)할 수 있는 파이썬 리스트입니다:
args = parser.parse_args()
for tag in args.tags:
print(tag)
Boolean Flags (store_true / store_false)
parser.add_argument(
"--dry-run",
action="store_true",
help="Simulate without writing"
)
parser.add_argument(
"--no-color",
action="store_false",
dest="color",
help="Disable color output"
)
사용법
python publish.py --dry-run # args.dry_run is True
python publish.py # args.dry_run is False
python publish.py --no-color # args.color is False
Sub‑commands (like git, docker, pip)
parser = argparse.ArgumentParser(description="Publish queue manager")
subparsers = parser.add_subparsers(dest="command", required=True)
# `publish` subcommand
publish_parser = subparsers.add_parser(
"publish",
help="Publish the next article in queue"
)
publish_parser.add_argument(
"--dry-run",
action="store_true",
help="Simulate without publishing"
)
# `list` subcommand
list_parser = subparsers.add_parser(
"list",
help="Show the publish queue"
)
list_parser.add_argument(
"--format",
choices=["table", "json"],
default="table"
)
args.command 은 어떤 서브커맨드가 선택되었는지를 알려 주며, 각 서브커맨드마다 고유한 인수가 있습니다.
--verbose / -v 패턴
런타임에 로깅 레벨을 설정하기 위해 --verbose를 사용하는 일반적인 패턴입니다:
import argparse
import logging
parser = argparse.ArgumentParser()
parser.add_argument(
"--verbose", "-v",
action="store_true",
help="Enable debug logging"
)
args = parser.parse_args()
logging.basicConfig(
level=logging.DEBUG if args.verbose else logging.INFO,
format="%(levelname)s: %(message)s"
)
log = logging.getLogger(__name__)
log.info("Starting...")
log.debug("This only shows with --verbose")
전체 예제: 기사 게시 대기열 CLI
#!/usr/bin/env python3
"""
publish_queue.py — CLI for managing the article publish queue.
Usage: python publish_queue.py [options]
"""
import argparse
import json
import logging
import sys
from pathlib import Path
QUEUE_FILE = Path("queue.json")
def load_queue() -> list[dict]:
"""Load the queue from JSON; return empty list if file missing."""
if not QUEUE_FILE.exists():
return []
return json.loads(QUEUE_FILE.read_text())
def save_queue(queue: list[dict]) -> None:
"""Write the queue back to disk."""
QUEUE_FILE.write_text(json.dumps(queue, indent=2))
def cmd_list(args: argparse.Namespace) -> None:
queue = load_queue()
if not queue:
print("Queue is empty.")
return
for i, article in enumerate(queue, 1):
status = "[published]" if article.get("published") else "[pending] "
tags = ", ".join(article.get("tags", []))
print(f"{i}. {status} {article['title']} ({tags})")
def cmd_add(args: argparse.Namespace) -> None:
queue = load_queue()
article = {
"title": args.title,
"tags": args.tags or [],
"published": False,
}
queue.append(article)
save_queue(queue)
logging.info("Added: %s", args.title)
print(f"Added '{args.title}' to queue. Total: {len(queue)} articles.")
def cmd_publish(args: argparse.Namespace) -> None:
queue = load_queue()
pending = [a for a in queue if not a.get("published")]
if not pending:
print("No pending articles.")
return
next_article = pending[0]
if args.dry_run:
print(f"[DRY RUN] Would publish: {next_article['title']}")
return
next_article["published"] = True
save_queue(queue)
print(f"Published: {next_article['title']}")
logging.info("Published: %s", next_article["title"])
def main() -> None:
parser = argparse.ArgumentParser(
description="Publish queue manager"
)
subparsers = parser.add_subparsers(dest="command", required=True)
# add subcommand
add_parser = subparsers.add_parser(
"add",
help="Add a new article to the queue"
)
add_parser.add_argument(
"--title",
required=True,
help="Article title (required)"
)
add_parser.add_argument(
"--tags",
nargs="*",
help="Zero or more tags"
)
add_parser.set_defaults(func=cmd_add)
# list subcommand
list_parser = subparsers.add_parser(
"list",
help="Show the publish queue"
)
list_parser.set_defaults(func=cmd_list)
# publish subcommand
publish_parser = subparsers.add_parser(
"publish",
help="Publish the next pending article"
)
publish_parser.add_argument(
"--dry-run",
action="store_true",
help="Simulate without publishing"
)
publish_parser.set_defaults(func=cmd_publish)
# global verbose flag
parser.add_argument(
"--verbose", "-v",
action="store_true",
help="Enable debug logging"
)
args = parser.parse_args()
# configure logging *after* parsing arguments
logging.basicConfig(
level=logging.DEBUG if args.verbose else logging.INFO,
format="%(levelname)s: %(message)s"
)
# dispatch to the chosen subcommand
args.func(args)
if __name__ == "__main__":
main()
스크립트를 다음과 같이 실행합니다:
python publish_queue.py add --title "My First Article" --tags python tutorial
python publish_queue.py list
python publish_queue.py publish --dry-run
python publish_queue.py publish -v
TL;DR
- **
argparse**는 한 줄 스크립트를 정교한 CLI로 변환합니다. - positional 및 optional 인자를 정의하고, type conversion, choices, 그리고 리스트를 위한 nargs를 사용합니다.
- 플래그에는
store_true/store_false를 사용합니다. - git 스타일 서브 커맨드를 위해 sub‑parsers 를 활용합니다.
- 로깅을 토글하기 위해
--verbose플래그를 추가합니다.
한번 시도해 보세요—스크립트가 몇 분 안에 더 견고하고, 자체 문서화되며, 사용자 친화적으로 변합니다!
publish_queue.py – Argument‑Parser 기반 CLI
import argparse
import logging
# Example logging call used by the script
logging.info("Published: %s", next_article["title"])
def build_parser() -> argparse.ArgumentParser:
"""Create the top‑level argument parser."""
parser = argparse.ArgumentParser(
prog="publish_queue",
description="Manage your article publish queue.",
)
parser.add_argument(
"--verbose", "-v",
action="store_true",
help="Enable debug logging",
)
subparsers = parser.add_subparsers(dest="command", required=True)
# ── list ────────────────────────────────────────────────────────
list_parser = subparsers.add_parser("list", help="Show the publish queue")
list_parser.set_defaults(func=cmd_list)
# ── add ────────────────────────────────────────────────────────
add_parser = subparsers.add_parser("add", help="Add an article to the queue")
add_parser.add_argument("--title", required=True, help="Article title")
add_parser.add_argument("--tags", nargs="*", help="Tags for the article")
add_parser.set_defaults(func=cmd_add)
# ── publish ─────────────────────────────────────────────────────
publish_parser = subparsers.add_parser(
"publish", help="Publish the next pending article"
)
publish_parser.add_argument(
"--dry-run", action="store_true", help="Simulate without writing"
)
publish_parser.set_defaults(func=cmd_publish)
return parser
def main() -> None:
"""Entry point for the CLI."""
parser = build_parser()
args = parser.parse_args()
logging.basicConfig(
level=logging.DEBUG if args.verbose else logging.INFO,
format="%(levelname)s: %(message)s",
)
# Dispatch to the appropriate sub‑command function
args.func(args)
if __name__ == "__main__":
main()
--help 출력
$ python publish_queue.py --help
usage: publish_queue [-h] [--verbose] {list,add,publish} ...
Manage your article publish queue.
positional arguments:
{list,add,publish}
list Show the publish queue
add Add an article to the queue
publish Publish the next pending article
options:
-h, --help show this help message and exit
--verbose, -v Enable debug logging
$ python publish_queue.py add --help
usage: publish_queue add [-h] --title TITLE [--tags [TAGS ...]]
options:
-h, --help show this help message and exit
--title TITLE Article title
--tags [TAGS ...] Tags for the article
예시 워크플로우
# Add articles to the queue
python publish_queue.py add --title "Python argparse guide" \
--tags python beginners tutorial
python publish_queue.py add --title "Automate your workflow" \
--tags python automation
# List the queue
python publish_queue.py list
# 1. [pending] Python argparse guide (python, beginners, tutorial)
# 2. [pending] Automate your workflow (python, automation)
# Publish the next article (dry‑run first)
python publish_queue.py publish --dry-run
# [DRY RUN] Would publish: Python argparse guide
python publish_queue.py publish
# Published: Python argparse guide
# Check the updated queue with debug logging
python publish_queue.py list --verbose
Argparse 패턴 요약
| 패턴 | 사용 시점 |
|---|---|
type=int / type=float | 모든 숫자 입력 |
choices=[...] | 고정된 유효 값 집합 |
required=True | 필수 옵션 인자 |
nargs="+" / nargs="*" | 값들의 리스트 |
action="store_true" | 불리언 플래그 |
add_subparsers() | 다중 명령 도구 |
set_defaults(func=…) | 서브 커맨드 함수에 디스패치 |
argparse가 자동으로 제공하는 것
-h/--help–help=문자열에서 자동 생성- Type validation – 명확한 오류 메시지, 트레이스백 없음
- Default values – 도움말 출력에 문서화
- Usage line – 인자 정의에서 자동 생성
제3자 라이브러리가 필요 없습니다. 모든 것이 파이썬 표준 라이브러리로 동작합니다.
추가 읽기 및 자료
- 전체 파이프라인에서 publish‑queue CLI – germy5.gumroad.com/l/xhxkzz (원하는 금액을 지불, 최소 $9.99)
- 자신을 검증하고 실행하는 첫 번째 자동화 파이썬 스크립트
- Python 로깅: 자동화 스크립트에서
print()사용 중단 - Cron으로 파이썬 스크립트 예약하기: 초보자를 위한 완전 가이드