Hướng dẫn phân tích cú pháp¶
- tác giả:
Tshepang Mbambo
Hướng dẫn này nhằm mục đích giới thiệu nhẹ nhàng về argparse, mô-đun phân tích cú pháp dòng lệnh được đề xuất trong thư viện chuẩn Python.
Ghi chú
Thư viện tiêu chuẩn bao gồm hai thư viện khác liên quan trực tiếp đến việc xử lý tham số dòng lệnh: mô-đun optparse cấp thấp hơn (có thể yêu cầu nhiều mã hơn để định cấu hình cho một ứng dụng nhất định nhưng cũng cho phép ứng dụng yêu cầu các hành vi mà argparse không hỗ trợ) và getopt cấp độ rất thấp (cụ thể đóng vai trò tương đương với dòng hàm getopt() có sẵn cho các lập trình viên C). Mặc dù cả hai mô-đun này đều không được đề cập trực tiếp trong hướng dẫn này nhưng nhiều khái niệm cốt lõi trong argparse có nguồn gốc đầu tiên từ optparse, vì vậy một số khía cạnh của hướng dẫn này cũng sẽ liên quan đến người dùng optparse.
Khái niệm¶
Hãy hiển thị loại chức năng mà chúng ta sẽ khám phá trong hướng dẫn giới thiệu này bằng cách sử dụng lệnh ls:
$ ls
cpython devguide prog.py pypy rm-unused-function.patch
$ ls pypy
ctypes_configure demo dotviewer bao gồm lib_pypy lib-python ...
$ ls -l
tổng cộng 20
drwxr-xr-x 19 wena wena 4096 18 tháng 2 18:51 cpython
drwxr-xr-x 4 wena wena 4096 ngày 8 tháng 2 12:04 devguide
-rwxr-xr-x 1 wena wena 535 Ngày 19 tháng 2 00:05 prog.py
drwxr-xr-x 14 wena wena 4096 Ngày 7 tháng 2 00:59 pypy
-rw-r--r-- 1 wena 741 Ngày 18 tháng 2 01:01 rm-unused-function.patch
$ ls --help
Cách sử dụng: ls [OPTION]... [FILE]...
Liệt kê thông tin về các FILE (thư mục hiện tại theo mặc định).
Sắp xếp các mục theo thứ tự bảng chữ cái nếu không chỉ định -cftuvSUX hay --sort.
...
Một số khái niệm chúng ta có thể học được từ bốn lệnh:
Lệnh ls rất hữu ích khi chạy mà không có bất kỳ tùy chọn nào. Nó mặc định hiển thị nội dung của thư mục hiện tại.
Nếu chúng tôi muốn nhiều hơn những gì nó cung cấp theo mặc định, chúng tôi sẽ nói với nó nhiều hơn một chút. Trong trường hợp này, chúng tôi muốn nó hiển thị một thư mục khác,
pypy. Những gì chúng tôi đã làm là xác định cái được gọi là đối số vị trí. Nó được đặt tên như vậy vì chương trình sẽ biết phải làm gì với giá trị, chỉ dựa vào vị trí nó xuất hiện trên dòng lệnh. Khái niệm này phù hợp hơn với lệnh như cp, lệnh có cách sử dụng cơ bản nhất làcp SRC DEST. Vị trí đầu tiên là what you want copied, và vị trí thứ hai là where you want it copied to.Bây giờ, giả sử chúng ta muốn thay đổi hành vi của chương trình. Trong ví dụ của chúng tôi, chúng tôi hiển thị thêm thông tin cho từng tệp thay vì chỉ hiển thị tên tệp.
-ltrong trường hợp đó được gọi là đối số tùy chọn.Đó là một đoạn văn bản trợ giúp. Nó rất hữu ích ở chỗ bạn có thể gặp một chương trình mà bạn chưa từng sử dụng trước đây và có thể tìm ra cách hoạt động của nó chỉ bằng cách đọc văn bản trợ giúp của nó.
Những điều cơ bản¶
Chúng ta hãy bắt đầu với một ví dụ rất đơn giản mà hầu như không làm gì cả:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
trình phân tích cú pháp.parse_args()
Sau đây là kết quả của việc chạy mã:
$ python prog.py
$ python prog.py --help
cách sử dụng: prog.py [-h]
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
$ python prog.py --verbose
cách sử dụng: prog.py [-h]
prog.py: lỗi: đối số không được nhận dạng: --verbose
$ python prog.py foo
cách sử dụng: prog.py [-h]
prog.py: lỗi: đối số không được nhận dạng: foo
Đây là những gì đang xảy ra:
Chạy tập lệnh mà không có bất kỳ tùy chọn nào sẽ không hiển thị gì cho thiết bị xuất chuẩn. Không hữu ích lắm.
Cái thứ hai bắt đầu hiển thị tính hữu ích của mô-đun
argparse. Chúng tôi hầu như không làm gì cả, nhưng chúng tôi đã nhận được một thông báo trợ giúp thú vị.Tùy chọn
--help, cũng có thể được rút ngắn thành-h, là tùy chọn duy nhất chúng tôi nhận được miễn phí (tức là không cần chỉ định nó). Chỉ định bất cứ điều gì khác dẫn đến một lỗi. Nhưng ngay cả khi đó, chúng tôi vẫn nhận được thông báo sử dụng hữu ích, cũng miễn phí.
Giới thiệu đối số vị trí¶
Một ví dụ:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
trình phân tích cú pháp.add_argument("echo")
args = trình phân tích cú pháp.parse_args()
in(args.echo)
Và chạy mã:
$ python prog.py
cách sử dụng: prog.py [-h] echo
prog.py: error: cần có các đối số sau: echo
$ python prog.py --help
cách sử dụng: prog.py [-h] echo
lập luận vị trí:
tiếng vọng
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
$ python prog.py foo
foo
Đây là những gì đang xảy ra:
Chúng tôi đã thêm phương thức
add_argument(), đây là phương thức chúng tôi sử dụng để chỉ định các tùy chọn dòng lệnh mà chương trình sẵn sàng chấp nhận. Trong trường hợp này, tôi đã đặt tên nó làechođể phù hợp với chức năng của nó.Việc gọi chương trình của chúng tôi bây giờ yêu cầu chúng tôi chỉ định một tùy chọn.
Phương thức
parse_args()thực sự trả về một số dữ liệu từ các tùy chọn được chỉ định, trong trường hợp này làecho.Biến này là một dạng 'ma thuật' nào đó mà
argparsethực hiện miễn phí (tức là không cần chỉ định giá trị đó được lưu trữ trong biến nào). Bạn cũng sẽ nhận thấy rằng tên của nó khớp với đối số chuỗi được cung cấp cho phương thức,echo.
Tuy nhiên, hãy lưu ý rằng, mặc dù màn hình trợ giúp trông rất đẹp nhưng hiện tại nó không hữu ích như mong đợi. For example we see that we got echo as a positional argument, but we don't know what it does, other than by guessing or by reading the source code. Vì vậy, hãy làm cho nó hữu ích hơn một chút:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("echo", help="echo chuỗi bạn sử dụng ở đây")
args = trình phân tích cú pháp.parse_args()
in(args.echo)
Và chúng tôi nhận được:
$ python prog.py -h
cách sử dụng: prog.py [-h] echo
lập luận vị trí:
echo echo chuỗi bạn sử dụng ở đây
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
Bây giờ, hãy làm điều gì đó hữu ích hơn nữa nhé:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("vuông", help="hiển thị bình phương của một số đã cho")
args = trình phân tích cú pháp.parse_args()
in(args.square**2)
Sau đây là kết quả của việc chạy mã:
$ python prog.py 4
Traceback (cuộc gọi gần đây nhất):
Tệp "prog.py", dòng 5, trong <module>
in(args.square**2)
TypeError: (các) loại toán hạng không được hỗ trợ cho ** hoặc pow(): 'str' và 'int'
Điều đó đã không diễn ra tốt đẹp. Đó là bởi vì argparse coi các tùy chọn mà chúng tôi cung cấp cho nó dưới dạng chuỗi, trừ khi chúng tôi nói khác. Vì vậy, hãy yêu cầu argparse coi đầu vào đó là số nguyên:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("vuông", help="hiển thị bình phương của một số đã cho",
loại=int)
args = trình phân tích cú pháp.parse_args()
in(args.square**2)
Sau đây là kết quả của việc chạy mã:
$ python prog.py 4
16
$ python prog.py bốn
cách sử dụng: prog.py [-h] vuông
prog.py: lỗi: đối số hình vuông: giá trị int không hợp lệ: 'bốn'
Việc đó diễn ra tốt đẹp. Chương trình thậm chí còn giúp loại bỏ đầu vào bất hợp pháp một cách hữu ích trước khi tiếp tục.
Introducing Optional arguments¶
Cho đến nay chúng ta đang chơi đùa với các lập luận về lập trường. Chúng ta hãy xem cách thêm những cái tùy chọn:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("--verbosity", help="tăng mức độ chi tiết đầu ra")
args = trình phân tích cú pháp.parse_args()
nếu args.verbosity:
print("bật tính chi tiết")
Và đầu ra:
$ python prog.py --verbosity 1
đã bật tính chi tiết
$ python prog.py
$ python prog.py --help
cách sử dụng: prog.py [-h] [--verbosity VERBOSITY]
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
--sự dài dòng VERBOSITY
tăng tính chi tiết đầu ra
$ python prog.py --verbosity
cách sử dụng: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: đối số --verbosity: mong đợi một đối số
Đây là những gì đang xảy ra:
Chương trình được viết để hiển thị nội dung nào đó khi
--verbosityđược chỉ định và không hiển thị gì khi không.Để chứng tỏ rằng tùy chọn này thực sự là tùy chọn, sẽ không có lỗi khi chạy chương trình mà không có tùy chọn này. Lưu ý rằng theo mặc định, nếu một đối số tùy chọn không được sử dụng thì biến có liên quan, trong trường hợp này là
args.verbosity, sẽ được gán một giá trị làNone, đó là lý do khiến nó không vượt qua được quá trình kiểm tra tính đúng của câu lệnhif.Thông báo trợ giúp hơi khác một chút.
Khi sử dụng tùy chọn
--verbosity, người ta cũng phải chỉ định một số giá trị, bất kỳ giá trị nào.
Ví dụ trên chấp nhận các giá trị số nguyên tùy ý cho --verbosity, nhưng đối với chương trình đơn giản của chúng ta, chỉ có hai giá trị thực sự hữu ích là True hoặc False. Hãy sửa đổi mã cho phù hợp:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("--verbose", help="tăng mức độ dài dòng đầu ra",
hành động="store_true")
args = trình phân tích cú pháp.parse_args()
nếu args.verbose:
print("bật tính chi tiết")
Và đầu ra:
$ python prog.py --verbose
đã bật tính chi tiết
$ python prog.py --verbose 1
cách sử dụng: prog.py [-h] [--verbose]
prog.py: lỗi: đối số không được nhận dạng: 1
$ python prog.py --help
cách sử dụng: prog.py [-h] [--verbose]
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
--verbose tăng mức độ dài dòng đầu ra
Đây là những gì đang xảy ra:
Tùy chọn bây giờ giống một lá cờ hơn là một thứ yêu cầu một giá trị. Chúng tôi thậm chí còn thay đổi tên của tùy chọn để phù hợp với ý tưởng đó. Lưu ý rằng bây giờ chúng ta chỉ định một từ khóa mới,
actionvà đặt cho nó giá trị"store_true". Điều này có nghĩa là, nếu tùy chọn được chỉ định, hãy gán giá trịTruechoargs.verbose. Không chỉ định nó ngụ ýFalse.Nó phàn nàn khi bạn chỉ định một giá trị, theo tinh thần thực sự của cờ.
Lưu ý văn bản trợ giúp khác nhau.
Tùy chọn ngắn¶
Nếu bạn đã quen với việc sử dụng dòng lệnh, bạn sẽ nhận thấy rằng tôi chưa đề cập đến chủ đề về các phiên bản ngắn của các tùy chọn. Nó khá đơn giản:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("-v", "--verbose", help="tăng mức độ chi tiết đầu ra",
hành động="store_true")
args = trình phân tích cú pháp.parse_args()
nếu args.verbose:
print("bật tính chi tiết")
Và đây là:
$ python prog.py -v
đã bật tính chi tiết
$ python prog.py --help
cách sử dụng: prog.py [-h] [-v]
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbose tăng độ dài đầu ra
Lưu ý rằng khả năng mới cũng được phản ánh trong văn bản trợ giúp.
Kết hợp các đối số vị trí và tùy chọn¶
Chương trình của chúng tôi ngày càng phức tạp:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
parser.add_argument("vuông", type=int,
help="hiển thị bình phương của một số đã cho")
parser.add_argument("-v", "--verbose", action="store_true",
help="tăng độ dài đầu ra")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.square**2
nếu args.verbose:
print(f"bình phương của {args.square} bằng {answer}")
khác:
in (câu trả lời)
Và bây giờ là đầu ra:
$ python prog.py
cách sử dụng: prog.py [-h] [-v] vuông
prog.py: lỗi: bắt buộc phải có các đối số sau: hình vuông
$ python prog.py 4
16
$ python prog.py 4 --verbose
bình phương của 4 bằng 16
$ python prog.py --verbose 4
bình phương của 4 bằng 16
Chúng tôi đã đưa ra một lập luận về lập trường, do đó có khiếu nại.
Lưu ý rằng thứ tự không quan trọng.
Hãy thử trả lại cho chương trình này của chúng tôi khả năng có nhiều giá trị chi tiết và thực sự sử dụng chúng:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
parser.add_argument("vuông", type=int,
help="hiển thị bình phương của một số đã cho")
trình phân tích cú pháp.add_argument("-v", "--verbosity", type=int,
help="tăng độ dài đầu ra")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.square**2
nếu args.verbosity == 2:
print(f"bình phương của {args.square} bằng {answer}")
Elif args.verbosity == 1:
print(f"{args.square}^2 == {answer}")
khác:
in (câu trả lời)
Và đầu ra:
$ python prog.py 4
16
$ python prog.py 4 -v
cách sử dụng: prog.py [-h] [-v VERBOSITY] vuông
prog.py: error: đối số -v/--verbosity: mong đợi một đối số
$ python prog.py 4 -v 1
4^2 == 16
$ python prog.py 4 -v 2
bình phương của 4 bằng 16
$ python prog.py 4 -v 3
16
Tất cả đều có vẻ ổn, ngoại trừ cái cuối cùng, nó bộc lộ một lỗi trong chương trình của chúng tôi. Hãy khắc phục bằng cách hạn chế các giá trị mà tùy chọn --verbosity có thể chấp nhận:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
parser.add_argument("vuông", type=int,
help="hiển thị bình phương của một số đã cho")
Parser.add_argument("-v", "--verbosity", type=int, Choices=[0, 1, 2],
help="tăng độ dài đầu ra")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.square**2
nếu args.verbosity == 2:
print(f"bình phương của {args.square} bằng {answer}")
Elif args.verbosity == 1:
print(f"{args.square}^2 == {answer}")
khác:
in (câu trả lời)
Và đầu ra:
$ python prog.py 4 -v 3
cách sử dụng: prog.py [-h] [-v {0,1,2}] vuông
prog.py: error: đối số -v/--verbosity: lựa chọn không hợp lệ: 3 (chọn từ 0, 1, 2)
$ python prog.py 4 -h
cách sử dụng: prog.py [-h] [-v {0,1,2}] vuông
lập luận vị trí:
hình vuông hiển thị hình vuông của một số cho trước
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbosity {0,1,2}
tăng tính chi tiết đầu ra
Lưu ý rằng thay đổi cũng phản ánh cả trong thông báo lỗi cũng như chuỗi trợ giúp.
Bây giờ, hãy sử dụng một cách tiếp cận khác để chơi với tính dài dòng, điều này khá phổ biến. Nó cũng khớp với cách tệp thực thi CPython xử lý đối số chi tiết của chính nó (kiểm tra đầu ra của python --help):
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
parser.add_argument("vuông", type=int,
help="hiển thị bình phương của một số đã cho")
parser.add_argument("-v", "--verbosity", action="count",
help="tăng độ dài đầu ra")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.square**2
nếu args.verbosity == 2:
print(f"bình phương của {args.square} bằng {answer}")
Elif args.verbosity == 1:
print(f"{args.square}^2 == {answer}")
khác:
in (câu trả lời)
Chúng tôi đã giới thiệu một hành động khác, "đếm", để đếm số lần xuất hiện của các tùy chọn cụ thể.
$ python prog.py 4
16
$ python prog.py 4 -v
4^2 == 16
$ python prog.py 4 -vv
bình phương của 4 bằng 16
$ python prog.py 4 --verbosity --verbosity
bình phương của 4 bằng 16
$ python prog.py 4 -v 1
cách sử dụng: prog.py [-h] [-v] vuông
prog.py: lỗi: đối số không được nhận dạng: 1
$ python prog.py 4 -h
cách sử dụng: prog.py [-h] [-v] vuông
lập luận vị trí:
hình vuông hiển thị hình vuông của một số cho trước
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbosity tăng mức độ dài dòng đầu ra
$ python prog.py 4 -vvv
16
Có, giờ đây nó giống một lá cờ hơn (tương tự như
action="store_true") trong phiên bản trước của tập lệnh của chúng tôi. Điều đó sẽ giải thích khiếu nại.Nó cũng hoạt động tương tự như hành động "store_true".
Bây giờ đây là minh họa cho tác dụng của hành động "đếm". Có thể bạn đã từng thấy cách sử dụng này trước đây.
Và nếu bạn không chỉ định cờ
-vthì cờ đó được coi là có giá trịNone.Đúng như mong đợi, khi chỉ định dạng dài của cờ, chúng ta sẽ nhận được kết quả tương tự.
Đáng buồn thay, kết quả trợ giúp của chúng tôi không cung cấp nhiều thông tin về khả năng mới mà tập lệnh của chúng tôi có được, nhưng điều đó luôn có thể được khắc phục bằng cách cải thiện tài liệu cho tập lệnh của chúng tôi (ví dụ: thông qua đối số từ khóa
help).Kết quả cuối cùng đó cho thấy một lỗi trong chương trình của chúng ta.
Hãy khắc phục:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
parser.add_argument("vuông", type=int,
help="hiển thị bình phương của một số đã cho")
parser.add_argument("-v", "--verbosity", action="count",
help="tăng độ dài đầu ra")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.square**2
# bugfix: thay thế == bằng >=
nếu args.verbosity >= 2:
print(f"bình phương của {args.square} bằng {answer}")
Elif args.verbosity >= 1:
print(f"{args.square}^2 == {answer}")
khác:
in (câu trả lời)
Và đây là những gì nó mang lại:
$ python prog.py 4 -vvv
bình phương của 4 bằng 16
$ python prog.py 4 -vvvv
bình phương của 4 bằng 16
$ python prog.py 4
Traceback (cuộc gọi gần đây nhất):
Tệp "prog.py", dòng 11, trong <module>
nếu args.verbosity >= 2:
TypeError: '>=' không được hỗ trợ giữa các phiên bản của 'NoneType' và 'int'
Đầu ra đầu tiên diễn ra tốt đẹp và sửa được lỗi chúng tôi gặp phải trước đó. Nghĩa là, chúng tôi muốn mọi giá trị >= 2 dài dòng nhất có thể.
Đầu ra thứ ba không tốt lắm.
Hãy sửa lỗi đó:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
parser.add_argument("vuông", type=int,
help="hiển thị bình phương của một số đã cho")
Parser.add_argument("-v", "--verbosity", action="count", default=0,
help="tăng độ dài đầu ra")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.square**2
nếu args.verbosity >= 2:
print(f"bình phương của {args.square} bằng {answer}")
Elif args.verbosity >= 1:
print(f"{args.square}^2 == {answer}")
khác:
in (câu trả lời)
Chúng tôi vừa giới thiệu một từ khóa khác, default. Chúng tôi đã đặt nó thành 0 để làm cho nó có thể so sánh được với các giá trị int khác. Hãy nhớ rằng theo mặc định, nếu đối số tùy chọn không được chỉ định, thì đối số đó sẽ nhận giá trị None và không thể so sánh với giá trị int (do đó có ngoại lệ TypeError).
Và:
$ python prog.py 4
16
Bạn có thể tiến khá xa chỉ với những gì chúng ta đã học được cho đến nay và chúng ta mới chỉ mới bắt đầu. Mô-đun argparse rất mạnh mẽ và chúng ta sẽ khám phá thêm một chút về nó trước khi kết thúc hướng dẫn này.
Tiến bộ hơn một chút¶
Điều gì sẽ xảy ra nếu chúng ta muốn mở rộng chương trình nhỏ bé của mình để thực hiện các lũy thừa khác, không chỉ hình vuông:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("x", type=int, help="the base")
Parser.add_argument("y", type=int, help="số mũ")
Parser.add_argument("-v", "--verbosity", action="count", default=0)
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.x**args.y
nếu args.verbosity >= 2:
print(f"{args.x} lũy thừa {args.y} bằng {answer}")
Elif args.verbosity >= 1:
print(f"{args.x}^{args.y} == {answer}")
khác:
in (câu trả lời)
Đầu ra:
$ python prog.py
cách sử dụng: prog.py [-h] [-v] x y
prog.py: error: bắt buộc phải có các đối số sau: x, y
$ python prog.py -h
cách sử dụng: prog.py [-h] [-v] x y
lập luận vị trí:
x cơ sở
y số mũ
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --sự dài dòng
$ python prog.py 4 2 -v
4^2 == 16
Lưu ý rằng cho đến nay chúng ta đang sử dụng mức độ chi tiết để change văn bản được hiển thị. Thay vào đó, ví dụ sau sử dụng mức độ chi tiết để hiển thị văn bản more
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
Parser.add_argument("x", type=int, help="the base")
Parser.add_argument("y", type=int, help="số mũ")
Parser.add_argument("-v", "--verbosity", action="count", default=0)
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.x**args.y
nếu args.verbosity >= 2:
print(f"Đang chạy '{__file__}'")
nếu args.verbosity >= 1:
print(f"{args.x}^{args.y} == ", end="")
in (câu trả lời)
Đầu ra:
$ python prog.py 4 2
16
$ python prog.py 4 2 -v
4^2 == 16
$ python prog.py 4 2 -vv
Đang chạy 'prog.py'
4^2 == 16
Chỉ định các đối số mơ hồ¶
Khi có sự mơ hồ trong việc quyết định xem một đối số là vị trí hay đối số, -- có thể được sử dụng để cho parse_args() biết rằng mọi thứ sau đó là đối số vị trí:
>>> trình phân tích cú pháp = argparse.ArgumentParser(prog='PROG')
>>> Parser.add_argument('-n', nargs='+')
>>> Parser.add_argument('args', nargs='*')
>>> # ambiguous, so parse_args assumes it's an option
>>> trình phân tích cú pháp.parse_args(['-f'])
cách sử dụng: PROG [-h] [-n N [N ...]] [args ...]
PROG: lỗi: đối số không được nhận dạng: -f
>>> Parser.parse_args(['--', '-f'])
Không gian tên(args=['-f'], n=None)
>>> # ambiguous nên tùy chọn -n tham lam chấp nhận đối số
>>> Parser.parse_args(['-n', '1', '2', '3'])
Không gian tên(args=[], n=['1', '2', '3'])
>>> Parser.parse_args(['-n', '1', '--', '2', '3'])
Namespace(args=['2', '3'], n=['1'])
Tùy chọn xung đột¶
Cho đến nay, chúng ta đã làm việc với hai phương thức của phiên bản argparse.ArgumentParser. Hãy giới thiệu cái thứ ba, add_mutually_exclusive_group(). Nó cho phép chúng ta chỉ định các tùy chọn xung đột với nhau. Chúng ta cũng hãy thay đổi phần còn lại của chương trình để chức năng mới có ý nghĩa hơn: chúng tôi sẽ giới thiệu tùy chọn --quiet, tùy chọn này sẽ ngược lại với tùy chọn --verbose:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser()
nhóm = trình phân tích cú pháp.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
Parser.add_argument("x", type=int, help="the base")
Parser.add_argument("y", type=int, help="số mũ")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.x**args.y
nếu args.quiet:
in (câu trả lời)
Elif args.verbose:
print(f"{args.x} lũy thừa {args.y} bằng {answer}")
khác:
print(f"{args.x}^{args.y} == {answer}")
Chương trình của chúng tôi bây giờ đơn giản hơn và chúng tôi đã mất một số chức năng để trình diễn. Dù sao, đây là đầu ra:
$ python prog.py 4 2
4^2 == 16
$ python prog.py 4 2 -q
16
$ python prog.py 4 2 -v
4 lũy thừa 2 bằng 16
$ python prog.py 4 2 -vq
cách sử dụng: prog.py [-h] [-v | -q] x y
prog.py: error: đối số -q/--quiet: không được phép với đối số -v/--verbose
$ python prog.py 4 2 -v --quiet
cách sử dụng: prog.py [-h] [-v | -q] x y
prog.py: error: đối số -q/--quiet: không được phép với đối số -v/--verbose
Điều đó sẽ dễ dàng để làm theo. Tôi đã thêm đầu ra cuối cùng đó để bạn có thể thấy mức độ linh hoạt mà bạn có được, tức là kết hợp các tùy chọn dạng dài với các tùy chọn dạng ngắn.
Trước khi chúng tôi kết luận, bạn có thể muốn cho người dùng biết mục đích chính của chương trình, phòng trường hợp họ không biết:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser(description="tính X lũy thừa của Y")
nhóm = trình phân tích cú pháp.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
Parser.add_argument("x", type=int, help="the base")
Parser.add_argument("y", type=int, help="số mũ")
args = trình phân tích cú pháp.parse_args()
câu trả lời = args.x**args.y
nếu args.quiet:
in (câu trả lời)
Elif args.verbose:
print(f"{args.x} lũy thừa {args.y} bằng {answer}")
khác:
print(f"{args.x}^{args.y} == {answer}")
Lưu ý rằng sự khác biệt nhỏ trong văn bản sử dụng. Lưu ý [-v | -q], nó cho chúng ta biết rằng chúng ta có thể sử dụng -v hoặc -q, nhưng không thể sử dụng cả hai cùng một lúc:
$ python prog.py --help
cách sử dụng: prog.py [-h] [-v | -q] x y
tính X theo lũy thừa của Y
lập luận vị trí:
x cơ sở
y số mũ
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbose
-q, --quiet
Cách dịch đầu ra argparse¶
Đầu ra của mô-đun argparse như văn bản trợ giúp và thông báo lỗi đều có thể dịch được bằng mô-đun gettext. Điều này cho phép các ứng dụng dễ dàng bản địa hóa các tin nhắn do argparse tạo ra. Xem thêm Quốc tế hóa các chương trình và mô-đun của bạn.
Chẳng hạn, trong đầu ra argparse này:
$ python prog.py --help
cách sử dụng: prog.py [-h] [-v | -q] x y
tính X theo lũy thừa của Y
lập luận vị trí:
x cơ sở
y số mũ
tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbose
-q, --quiet
Các chuỗi usage:, positional arguments:, options: và show this help message and exit đều có thể dịch được.
Để dịch các chuỗi này, trước tiên chúng phải được trích xuất thành tệp .po. Ví dụ: sử dụng Babel, hãy chạy lệnh này:
$ trích xuất pybabel -o messages.po /usr/lib/python3.12/argparse.py
Lệnh này sẽ trích xuất tất cả các chuỗi có thể dịch được từ mô-đun argparse và xuất chúng thành một tệp có tên messages.po. Lệnh này giả định rằng cài đặt Python của bạn ở /usr/lib.
Bạn có thể tìm ra vị trí của mô-đun argparse trên hệ thống của mình bằng tập lệnh này
nhập khẩu argparse
in(argparse.__file__)
Khi các tin nhắn trong tệp .po được dịch và các bản dịch được cài đặt bằng gettext, argparse sẽ có thể hiển thị các tin nhắn đã dịch.
Để dịch các chuỗi của riêng bạn ở đầu ra argparse, hãy sử dụng gettext.
Bộ chuyển đổi loại tùy chỉnh¶
Mô-đun argparse cho phép bạn chỉ định trình chuyển đổi loại tùy chỉnh cho các đối số dòng lệnh của mình. Điều này cho phép bạn sửa đổi dữ liệu đầu vào của người dùng trước khi nó được lưu trữ trong argparse.Namespace. Điều này có thể hữu ích khi bạn cần xử lý trước dữ liệu đầu vào trước khi nó được sử dụng trong chương trình của bạn.
Khi sử dụng trình chuyển đổi loại tùy chỉnh, bạn có thể sử dụng bất kỳ lệnh gọi nào có đối số chuỗi đơn (giá trị đối số) và trả về giá trị được chuyển đổi. Tuy nhiên, nếu cần xử lý các tình huống phức tạp hơn, bạn có thể sử dụng lớp hành động tùy chỉnh với tham số action.
Ví dụ: giả sử bạn muốn xử lý các đối số có tiền tố khác nhau và xử lý chúng cho phù hợp:
nhập khẩu argparse
trình phân tích cú pháp = argparse.ArgumentParser(prefix_chars='-+')
parser.add_argument('-a', metavar='<value>', action='append',
type=lambda x: ('-', x))
parser.add_argument('+a', metavar='<value>', action='append',
type=lambda x: ('+', x))
args = trình phân tích cú pháp.parse_args()
in(args)
Đầu ra:
$ python prog.py -a value1 +a value2
Không gian tên(a=[('-', 'value1'), ('+', 'value2')])
Trong ví dụ này, chúng tôi:
Đã tạo trình phân tích cú pháp có các ký tự tiền tố tùy chỉnh bằng tham số
prefix_chars.Đã xác định hai đối số,
-avà+a, sử dụng tham sốtypeđể tạo bộ chuyển đổi loại tùy chỉnh nhằm lưu trữ giá trị trong một bộ dữ liệu có tiền tố.
Nếu không có bộ chuyển đổi loại tùy chỉnh, các đối số sẽ coi -a và +a là cùng một đối số, điều này sẽ không mong muốn. Bằng cách sử dụng trình chuyển đổi loại tùy chỉnh, chúng tôi có thể phân biệt giữa hai đối số.
Kết luận¶
Mô-đun argparse cung cấp nhiều hơn những gì được hiển thị ở đây. Tài liệu của nó khá chi tiết, kỹ lưỡng và có đầy đủ các ví dụ. Sau khi xem qua hướng dẫn này, bạn sẽ dễ dàng tiếp thu chúng mà không cảm thấy choáng ngợp.