Nếu script Python của bạn vẫn đọc tham số bằng sys.argv[1], sys.argv[2] rồi tự kiểm tra len(sys.argv), hãy đổi sang argparse. Chỉ với vài dòng khai báo, argparse tự sinh –help, tự validate kiểu dữ liệu và báo lỗi rõ ràng — script của bạn thành một công cụ dòng lệnh chuyên nghiệp mà không cần cài thêm thư viện nào, vì argparse đã có sẵn trong thư viện chuẩn.

Vấn đề

Giả sử bạn viết script convert.py để chuyển file CSV thành JSON, nhận vào đường dẫn file và số dòng cần lấy. Cách thủ công thường thấy là đọc sys.argv rồi tự kiểm tra từng vị trí. Nó chạy được, nhưng rất giòn: quên tham số thì dính IndexError, nhập chữ vào chỗ cần số thì ValueError kèm traceback khó đọc, và người dùng mới không biết script nhận những tham số gì nếu không mở code ra xem. Thêm tham số tùy chọn, đoạn kiểm tra tay càng phình ra và càng dễ sai.

import sys
# Cách thủ công: đọc sys.argv, tự kiểm tra từng vị trí
if len(sys.argv) < 3:
print("Dùng: python convert.py <file.csv> <so_dong>")
sys.exit(1)
path = sys.argv[1]
limit = int(sys.argv[2]) # nhập chữ -> ValueError, crash không báo rõ

Giải pháp

argparse giải quyết đúng ba điểm yếu trên bằng cách khai báo thay vì kiểm tra tay. Bạn mô tả từng tham số một lần: tên, kiểu dữ liệu, giá trị mặc định, mô tả ngắn. Phần còn lại argparse lo: tự ép kiểu và báo lỗi khi sai, tự sinh –help, tự in hướng dẫn khi thiếu tham số bắt buộc.

import argparse
parser = argparse.ArgumentParser(
description="Chuyển CSV thành JSON, chỉ lấy N dòng đầu."
)
parser.add_argument("file", help="Đường dẫn file CSV đầu vào")
parser.add_argument("--limit", type=int, default=10,
help="Số dòng cần lấy (mặc định: 10)")
parser.add_argument("--pretty", action="store_true",
help="In JSON đẹp, có thụt dòng")
args = parser.parse_args()
print(args.file, args.limit, args.pretty)

Chạy thử ba lệnh sau:

  • python convert.py --help — in bảng mô tả đầy đủ từng tham số.
  • python convert.py data.csv --limit 5 --pretty — args.limit là số nguyên 5, args.pretty là True.
  • python convert.py data.csv --limit abc — argparse chặn ngay từ cổng, báo invalid int value và in lại hướng dẫn, thoát với mã lỗi 2 thay vì văng traceback.

Khi công cụ lớn dần thành nhiều lệnh con, ví dụ tool import và tool export, argparse có sẵn subparsers để tách mỗi lệnh thành một parser riêng mà vẫn giữ chung một –help ở cấp cao nhất. Mỗi lệnh con khai báo tham số của riêng nó, người dùng gõ tool import –file data.csv là đủ.

import argparse
parser = argparse.ArgumentParser(description="Công cụ xử lý dữ liệu.")
sub = parser.add_subparsers(dest="cmd", required=True)
p_import = sub.add_parser("import", help="Nhập dữ liệu vào DB")
p_import.add_argument("--file", required=True)
p_export = sub.add_parser("export", help="Xuất dữ liệu ra CSV")
p_export.add_argument("--out", default="out.csv")
args = parser.parse_args()
print(args)

Áp dụng vào dự án của bạn

Bắt đầu từ script nhỏ nhất bạn dùng hằng ngày: seed dữ liệu, dọn file tạm, kiểm tra trạng thái API. Đổi phần đọc sys.argv sang argparse, thêm –help và giá trị mặc định cho mọi tham số tùy chọn. Khi CLI vượt quá vài lệnh con lồng nhau hoặc cần gợi ý tự động trên terminal, lúc đó mới cân nhắc Click hoặc Typer — còn với đa số script nội bộ, argparse là đủ và không thêm phụ thuộc nào.

Bài viết liên quan

Câu hỏi thường gặp

argparse khác gì so với đọc sys.argv trực tiếp?

sys.argv chỉ là một danh sách chuỗi thô, mọi kiểm tra đều do bạn tự viết. argparse thêm lên trên nó ba thứ: validate kiểu dữ liệu, sinh –help tự động và báo lỗi kèm hướng dẫn sử dụng.

Khi nào nên dùng Click hoặc Typer thay cho argparse?

Khi CLI có nhiều lệnh lồng nhau, cần màu sắc, thanh tiến trình hoặc gợi ý tự động trên terminal. Với script một file và vài tham số, argparse gọn hơn, không cần cài thêm gì.

Làm sao bắt buộc người dùng phải nhập một option –flag?

Truyền required=True khi khai báo, ví dụ parser.add_argument(‘–file’, required=True). Thiếu nó, argparse tự báo lỗi và in hướng dẫn.

Nhập sai kiểu dữ liệu, ví dụ –limit abc, thì chuyện gì xảy ra?

argparse chặn ngay khi parse, in thông báo invalid int value kèm hướng dẫn sử dụng rồi thoát với mã lỗi 2. Chương trình không chạy tiếp và không văng traceback ra màn hình.

💬 Bạn đã thử cách này trong dự án của mình chưa? Nếu gặp lỗi hoặc có cách làm gọn hơn, để lại bình luận bên dưới — mình đọc hết và sẽ bổ sung những ý hay vào bài.

Nguồn tham khảo