Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Hướng dẫn giới hạn giá trị tham số với choices trong argparse Python

Giới thiệu

Khi viết chương trình dòng lệnh (CLI) với argparse, thường cần giới hạn giá trị người dùng có thể nhập cho một đối số. Ví dụ: số lượng Grand Slam titles của cầu thủ tennis chỉ từ 0 đến 20 (tính đến 2020).

Vấn đề: Chưa giới hạn giá trị

import argparse

def get_args():
    parser = argparse.ArgumentParser(
        description='Ví dụ đối số vị trí',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument('titles', metavar='titles', type=int, help='Số GrandSlam titles')
    return parser.parse_args()

def main(titles):
    print(f"*** Cầu thủ đã thắng {titles} GrandSlam titles.")

if __name__ == '__main__':
    args = get_args()
    main(args.titles)

Chạy thử:

$ python test.py 20
*** Cầu thủ đã thắng 20 GrandSlam titles.

$ python test.py 50
*** Cầu thủ đã thắng 50 GrandSlam titles.  ← Sai logic!

$ python test.py -1
*** Cầu thủ đã thắng -1 GrandSlam titles.  ← Sai logic!

Giải pháp: Sử dụng tham số choices

Tham số choices nhận một iterable (list, range, tuple...) chứa các giá trị hợp lệ. argparse sẽ tự động kiểm tra và báo lỗi nếu giá trị nhập vào không nằm trong danh sách.

import argparse

def get_args():
    parser = argparse.ArgumentParser(
        description='Ví dụ đối số vị trí với choices',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    # Giới hạn titles từ 0 đến 19 (range(0, 20) không bao gồm 20)
    parser.add_argument('titles', metavar='titles', type=int, 
                        choices=range(0, 20), help='GrandSlam Titles (0-19)')
    return parser.parse_args()

def main(titles):
    print(f"*** Cầu thủ đã thắng {titles} GrandSlam titles.")

if __name__ == '__main__':
    args = get_args()
    main(args.titles)

Kết quả

$ python test.py 30
usage: test.py [-h] titles
test.py: error: argument titles: invalid choice: 30 (choose from 0, 1, 2, ..., 19)

$ python test.py 10
*** Cầu thủ đã thắng 10 GrandSlam titles.

$ python test.py -1
usage: test.py [-h] titles
test.py: error: argument titles: invalid choice: -1 (choose from 0, 1, 2, ..., 19)

$ python test.py 0
*** Cầu thủ đã thắng 0 GrandSlam titles.

$ python test.py 20
usage: test.py [-h] titles
test.py: error: argument titles: invalid choice: 20 (choose from 0, 1, 2, ..., 19)

Kết hợp với đối số chuỗi (string choices)

import argparse

def get_args():
    parser = argparse.ArgumentParser(
        description='Ví dụ nhiều đối số với choices',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument('player', metavar='player', type=str,
                        choices=['federer', 'nadal', 'djokovic'],
                        help='Tennis Players')
    parser.add_argument('titles', metavar='titles', type=int,
                        choices=range(0, 20),
                        help='GrandSlam Titles')
    return parser.parse_args()

def main(player, titles):
    print(f"*** {player} đã thắng {titles} GrandSlam titles.")

if __name__ == '__main__':
    args = get_args()
    main(args.player, args.titles)
$ python test.py "djokovic" 17
*** djokovic đã thắng 17 GrandSlam titles.

$ python test.py "murray" 5
usage: test.py [-h] player titles
test.py: error: argument player: invalid choice: 'murray' (choose from 'federer', 'nadal', 'djokovic')

Tóm tắt

  • choices nhận list/tuple/range các giá trị hợp lệ.
  • argparse tự động validate và hiển thị danh sách lựa chọn khi lỗi.
  • Áp dụng được cho cả kiểu int, str và các kiểu khác.
  • Giúp tăng tính robust cho CLI mà không cần viết code kiểm tra thủ công.