⌨️
실습 프로젝트 (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 와 동일▶ 실행 결과
(예제 참고)