← 파이썬 강의 목록으로
⌨️
실습 프로젝트 (Practice) · ★★★★
subparsers + JSON

Lv4 · argparse 기반 CLI

argparse 의 subparsers 로 진짜 CLI 도구처럼 동작하는 To-Do. add/list/done/del + --version + --help 를 갖춥니다.

argparsesubparserJSON
소요 시간
5~8시간
난이도
📊 고급 응용
선수 조건
🎯 고급 1, 9주차
결과물
실제 배포 가능한 CLI 형태

이 강의에서 배우는 것

  • 1argparse subparsers 로 서브 커맨드 구현
  • 2각 커맨드를 함수로 분리하고 set_defaults(func=...)
  • 3--version, --help 자동 생성

프로젝트 개요

  • todo add '우유 사기' --priority high
  • todo list --only-pending
  • todo done 3 / todo del 3
  • todo --version

도전 과제

  • click 으로 재작성 비교
  • rich 컬러 출력

채점 체크리스트

  • subparsers 사용
  • 함수 분리
  • JSON 영구 저장

💻 예제 (examples)

실제로 실행해 결과를 확인할 수 있는 예제 코드입니다.

solution.py전체 동작 코드
CODE
"""argparse 기반 To-Do CLI"""
import argparse
import json
from pathlib import Path

DB = Path("todos_cli.json")

def load():
    return json.loads(DB.read_text(encoding="utf-8")) if DB.exists() else []

def save(items):
    DB.write_text(json.dumps(items, ensure_ascii=False, indent=2), encoding="utf-8")

def cmd_add(args):
    items = load()
    items.append({
        "id": len(items) + 1,
        "task": args.task,
        "priority": args.priority,
        "done": False,
    })
    save(items)
    print(f"추가됨 #{items[-1]['id']}: {args.task}")

def cmd_list(args):
    items = load()
    if args.only_pending:
        items = [i for i in items if not i["done"]]
    if not items:
        print("(비어있음)"); return
    for it in items:
        mark = "[x]" if it["done"] else "[ ]"
        print(f"{it['id']:>3}. {mark}[{it['priority']}] {it['task']}")

def cmd_done(args):
    items = load()
    for it in items:
        if it["id"] == args.id:
            it["done"] = True
            save(items)
            print(f"#{args.id} 완료")
            return
    print(f"#{args.id} 없음")

def cmd_del(args):
    items = load()
    new_items = [i for i in items if i["id"] != args.id]
    if len(new_items) == len(items):
        print(f"#{args.id} 없음"); return
    save(new_items)
    print(f"#{args.id} 삭제")

def build_parser():
    p = argparse.ArgumentParser(prog="todo")
    p.add_argument("--version", action="version", version="todo 1.0.0")
    sub = p.add_subparsers(dest="cmd", required=True)

    add = sub.add_parser("add")
    add.add_argument("task")
    add.add_argument("--priority", choices=["low", "high"], default="low")
    add.set_defaults(func=cmd_add)

    lst = sub.add_parser("list")
    lst.add_argument("--only-pending", action="store_true")
    lst.set_defaults(func=cmd_list)

    done = sub.add_parser("done")
    done.add_argument("id", type=int)
    done.set_defaults(func=cmd_done)

    delcmd = sub.add_parser("del")
    delcmd.add_argument("id", type=int)
    delcmd.set_defaults(func=cmd_del)

    return p

def main():
    args = build_parser().parse_args()
    args.func(args)

if __name__ == "__main__":
    main()
▶ 실행 결과
$ python solution.py add "우유 사기" --priority high
추가됨 #1: 우유 사기

$ python solution.py list
  1. [ ][high] 우유 사기

$ python solution.py done 1
#1 완료

$ python solution.py --version
todo 1.0.0

📝 과제 (exercises)

직접 풀어보고, 막힐 때 정답을 펼쳐 비교해보세요.

과제 1

프로젝트 구현

목표: 위 사양대로 직접 작성한다.

요구사항
  • subparsers
  • set_defaults(func=...)
  • --version
💡 힌트

sub = p.add_subparsers(dest='cmd', required=True)

입출력 예시
todo 1.0.0
채점
  • · 서브커맨드 동작
  • · JSON 저장
정답 코드 펼치기 / 접기
SOLUTION
# 위 solution.py 와 동일
▶ 실행 결과
(예제 참고)
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗