optparse --- Trình phân tích cú pháp cho các tùy chọn dòng lệnh¶
Source code: Lib/optparse.py
Chọn thư viện phân tích đối số¶
Thư viện chuẩn bao gồm ba thư viện phân tích đối số:
getopt: một mô-đun phản ánh chặt chẽ thủ tục CgetoptAPI. Được bao gồm trong thư viện chuẩn kể từ trước khi phát hành Python 1.0 ban đầu.optparse: một sự thay thế khai báo chogetoptcung cấp chức năng tương đương mà không yêu cầu mỗi ứng dụng triển khai logic phân tích cú pháp tùy chọn thủ tục của riêng nó. Được bao gồm trong thư viện chuẩn kể từ khi phát hành Python 2.3.argparse: một giải pháp thay thế đáng tin cậy hơn chooptparse, cung cấp nhiều chức năng hơn theo mặc định, nhưng lại làm giảm tính linh hoạt của ứng dụng trong việc kiểm soát chính xác cách xử lý đối số. Được bao gồm trong thư viện chuẩn kể từ bản phát hành Python 2.7 và Python 3.2.
Trong trường hợp không có các ràng buộc thiết kế phân tích cú pháp đối số cụ thể hơn, argparse là lựa chọn được đề xuất để triển khai các ứng dụng dòng lệnh vì nó cung cấp chức năng cơ bản ở mức cao nhất với ít mã cấp ứng dụng nhất.
getopt được giữ lại gần như hoàn toàn vì lý do tương thích ngược. Tuy nhiên, nó cũng phục vụ một trường hợp sử dụng thích hợp như một công cụ để tạo nguyên mẫu và kiểm tra việc xử lý đối số dòng lệnh trong các ứng dụng C dựa trên getopt.
optparse nên được coi là thay thế cho argparse trong các trường hợp sau:
một ứng dụng đã sử dụng
optparsevà không muốn mạo hiểm với những thay đổi hành vi tinh vi có thể phát sinh khi di chuyển sangargparseứng dụng yêu cầu quyền kiểm soát bổ sung đối với cách xen kẽ các tùy chọn và tham số vị trí trên dòng lệnh (bao gồm khả năng tắt hoàn toàn tính năng xen kẽ)
ứng dụng yêu cầu kiểm soát bổ sung đối với việc phân tích cú pháp gia tăng các thành phần dòng lệnh (mặc dù
argparsecó hỗ trợ điều này, nhưng cách hoạt động chính xác của nó trong thực tế là không mong muốn đối với một số trường hợp sử dụng)ứng dụng yêu cầu quyền kiểm soát bổ sung đối với việc xử lý các tùy chọn chấp nhận các giá trị tham số có thể bắt đầu bằng
-(chẳng hạn như các tùy chọn được ủy quyền sẽ được chuyển đến các quy trình con được gọi)ứng dụng yêu cầu một số hành vi xử lý tham số dòng lệnh khác mà
argparsekhông hỗ trợ, nhưng có thể được triển khai theo giao diện cấp thấp hơn dooptparsecung cấp
Những cân nhắc này cũng có nghĩa là optparse có khả năng cung cấp nền tảng tốt hơn cho các tác giả thư viện viết thư viện xử lý đối số dòng lệnh của bên thứ ba.
Để làm ví dụ cụ thể, hãy xem xét hai cấu hình phân tích cú pháp đối số dòng lệnh sau, cấu hình đầu tiên sử dụng optparse và cấu hình thứ hai sử dụng argparse:
nhập khẩu optparse
nếu __name__ == '__main__':
trình phân tích cú pháp = optparse.OptionParser()
parser.add_option('-o', '--output')
parser.add_option('-v', dest='verbose', action='store_true')
opts, args = parser.parse_args()
quá trình (args, đầu ra=opts.output, chi tiết=opts.verbose)
nhập khẩu argparse
nếu __name__ == '__main__':
trình phân tích cú pháp = argparse.ArgumentParser()
parser.add_argument('-o', '--output')
parser.add_argument('-v', dest='verbose', action='store_true')
parser.add_argument('rest', nargs='*')
args = trình phân tích cú pháp.parse_args()
quá trình(args.rest, đầu ra=args.output, chi tiết=args.verbose)
Sự khác biệt rõ ràng nhất là ở phiên bản optparse, các đối số không phải tùy chọn được ứng dụng xử lý riêng sau khi quá trình xử lý tùy chọn hoàn tất. Trong phiên bản argparse, các đối số vị trí được khai báo và xử lý giống như các tùy chọn đã đặt tên.
Tuy nhiên, phiên bản argparse cũng sẽ xử lý một số tổ hợp tham số khác với cách phiên bản optparse xử lý chúng. Ví dụ (trong số những khác biệt khác):
việc cung cấp
-o -vsẽ mang lạioutput="-v"vàverbose=Falsekhi sử dụngoptparse, nhưng có lỗi sử dụng vớiargparse(phàn nàn rằng không có giá trị nào được cung cấp cho-o/--output, vì-vđược hiểu là cờ chi tiết)tương tự, việc cung cấp
-o --sẽ mang lạioutput="--"vàargs=()khi sử dụngoptparse, nhưng có lỗi sử dụng vớiargparse(cũng phàn nàn rằng không có giá trị nào được cung cấp cho-o/--output, vì--được hiểu là chấm dứt quá trình xử lý tùy chọn và coi tất cả các giá trị còn lại là đối số vị trí)việc cung cấp
-o=foosẽ cung cấpoutput="=foo"khi sử dụngoptparse, nhưng cung cấpoutput="foo"vớiargparse(vì=được đặt trong trường hợp đặc biệt như một dấu phân cách thay thế cho các giá trị tham số tùy chọn)
Việc những hành vi khác nhau này trong phiên bản argparse được coi là mong muốn hay có vấn đề sẽ tùy thuộc vào trường hợp sử dụng ứng dụng dòng lệnh cụ thể.
Xem thêm
click là thư viện xử lý đối số của bên thứ ba (ban đầu dựa trên optparse), cho phép phát triển các ứng dụng dòng lệnh dưới dạng một tập hợp các chức năng thực thi lệnh được trang trí.
Các thư viện bên thứ ba khác, chẳng hạn như typer hoặc msgspec-click, cho phép chỉ định giao diện dòng lệnh theo cách tích hợp hiệu quả hơn với việc kiểm tra tĩnh các chú thích loại Python.
Giới thiệu¶
optparse là một thư viện thuận tiện, linh hoạt và mạnh mẽ hơn để phân tích các tùy chọn dòng lệnh so với mô-đun getopt tối giản. optparse sử dụng kiểu phân tích cú pháp dòng lệnh mang tính khai báo hơn: bạn tạo một phiên bản của OptionParser, điền vào đó các tùy chọn và phân tích cú pháp dòng lệnh. optparse cho phép người dùng chỉ định các tùy chọn theo cú pháp GNU/POSIX thông thường, đồng thời tạo thêm thông báo sử dụng và trợ giúp cho bạn.
Đây là ví dụ về cách sử dụng optparse trong một tập lệnh đơn giản:
từ nhập optparse OptionParser
...
trình phân tích cú pháp = OptionParser()
parser.add_option("-f", "--file", dest="filename",
help="viết báo cáo cho FILE", metavar="FILE")
trình phân tích cú pháp.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="không in thông báo trạng thái ra thiết bị xuất chuẩn")
(tùy chọn, args) = trình phân tích cú pháp.parse_args()
Với một vài dòng mã này, người dùng tập lệnh của bạn giờ đây có thể thực hiện "việc thông thường" trên dòng lệnh, ví dụ:
<yourscript> --file=outfile -q
Khi phân tích cú pháp dòng lệnh, optparse đặt các thuộc tính của đối tượng options được parse_args() trả về dựa trên các giá trị dòng lệnh do người dùng cung cấp. Khi parse_args() trả về từ việc phân tích dòng lệnh này, options.filename sẽ là "outfile" và options.verbose sẽ là False. optparse hỗ trợ cả tùy chọn dài và ngắn, cho phép hợp nhất các tùy chọn ngắn với nhau và cho phép các tùy chọn được liên kết với các đối số của chúng theo nhiều cách khác nhau. Do đó, các dòng lệnh sau đều tương đương với ví dụ trên:
<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile
Ngoài ra, người dùng có thể chạy một trong các thao tác sau
<yourscript> -h
<yourscript> --help
và optparse sẽ in ra bản tóm tắt ngắn gọn về các tùy chọn của tập lệnh của bạn:
Cách sử dụng: <yourscript> [tùy chọn]
Tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-f FILE, --file=FILE viết báo cáo cho FILE
-q, --quiet không in thông báo trạng thái ra thiết bị xuất chuẩn
trong đó giá trị của yourscript được xác định trong thời gian chạy (thông thường từ sys.argv[0]).
Nền¶
optparse được thiết kế rõ ràng để khuyến khích việc tạo ra các chương trình có giao diện dòng lệnh đơn giản tuân theo các quy ước được thiết lập bởi dòng hàm getopt() dành cho các nhà phát triển C. Cuối cùng, nó chỉ hỗ trợ cú pháp dòng lệnh và ngữ nghĩa phổ biến nhất được sử dụng thông thường trong Unix. Nếu bạn không quen với những quy ước này, việc đọc phần này sẽ giúp bạn làm quen với chúng.
Thuật ngữ¶
- lý lẽ
một chuỗi được nhập trên dòng lệnh và được shell chuyển tới
execl()hoặcexecv(). Trong Python, đối số là các phần tử củasys.argv[1:](sys.argv[0]là tên của chương trình đang được thực thi). Hệ vỏ Unix cũng sử dụng thuật ngữ "word".Đôi khi bạn nên thay thế một danh sách đối số khác với
sys.argv[1:], vì vậy bạn nên đọc "đối số" là "một phần tử củasys.argv[1:]hoặc của một số danh sách khác được cung cấp để thay thế chosys.argv[1:]".- tùy chọn
một đối số được sử dụng để cung cấp thêm thông tin nhằm hướng dẫn hoặc tùy chỉnh việc thực hiện chương trình. Có nhiều cú pháp khác nhau cho các tùy chọn; cú pháp Unix truyền thống là dấu gạch nối ("-") theo sau là một chữ cái, ví dụ:
-xhoặc-F. Ngoài ra, cú pháp Unix truyền thống cho phép hợp nhất nhiều tùy chọn thành một đối số duy nhất, ví dụ:-x -Ftương đương với-xF. Dự án GNU đã giới thiệu--, theo sau là một loạt các từ được phân tách bằng dấu gạch nối, ví dụ:--filehoặc--dry-run. Đây là hai cú pháp tùy chọn duy nhất được cung cấp bởioptparse.Một số cú pháp tùy chọn khác mà thế giới đã thấy bao gồm:
một dấu gạch nối theo sau là một vài chữ cái, ví dụ:
-pf(đây là not giống như nhiều tùy chọn được hợp nhất thành một đối số duy nhất)một dấu gạch nối theo sau là cả một từ, ví dụ:
-file(cú pháp này về mặt kỹ thuật tương đương với cú pháp trước đó, nhưng chúng thường không xuất hiện trong cùng một chương trình)dấu cộng theo sau là một chữ cái hoặc một vài chữ cái hoặc một từ, ví dụ:
+f,+rgbmột dấu gạch chéo theo sau là một chữ cái, hoặc một vài chữ cái hoặc một từ, ví dụ:
/f,/file
Các cú pháp tùy chọn này không được
optparsehỗ trợ và sẽ không bao giờ như vậy. Điều này là có chủ ý: ba cái đầu tiên không chuẩn trên mọi môi trường và cái cuối cùng chỉ có ý nghĩa nếu bạn chỉ nhắm mục tiêu đến Windows hoặc một số nền tảng cũ nhất định (ví dụ: VMS, MS-DOS).- đối số tùy chọn
một đối số theo sau một tùy chọn, được liên kết chặt chẽ với tùy chọn đó và được sử dụng từ danh sách đối số khi có tùy chọn đó. Với
optparse, các đối số tùy chọn có thể nằm trong một đối số riêng biệt với tùy chọn của chúng:-f foo --file foo
hoặc được bao gồm trong cùng một đối số:
-ffoo --file=foo
Thông thường, một tùy chọn nhất định có thể nhận một đối số hoặc không. Nhiều người muốn có tính năng "đối số tùy chọn tùy chọn", nghĩa là một số tùy chọn sẽ nhận đối số nếu họ nhìn thấy nó và sẽ không nhận nếu không. Điều này hơi gây tranh cãi vì nó làm cho việc phân tích cú pháp trở nên mơ hồ: nếu
-anhận một đối số tùy chọn và-bhoàn toàn là một tùy chọn khác, thì chúng ta diễn giải-abnhư thế nào? Vì sự mơ hồ này nênoptparsekhông hỗ trợ tính năng này.- đối số vị trí
nội dung nào đó còn sót lại trong danh sách đối số sau khi các tùy chọn đã được phân tích cú pháp, tức là sau khi các tùy chọn và đối số của chúng đã được phân tích cú pháp và xóa khỏi danh sách đối số.
- tùy chọn bắt buộc
một tùy chọn phải được cung cấp trên dòng lệnh; lưu ý rằng cụm từ "tùy chọn bắt buộc" là tự mâu thuẫn trong tiếng Anh.
optparsekhông ngăn cản bạn triển khai các tùy chọn bắt buộc nhưng cũng không giúp ích gì nhiều cho bạn.
Ví dụ: hãy xem xét dòng lệnh giả định này
prog -v --report report.txt thanh foo
-v và --report đều là những lựa chọn. Giả sử --report nhận một đối số thì report.txt là một đối số tùy chọn. foo và bar là các đối số vị trí.
Tùy chọn cho là gì?¶
Các tùy chọn được sử dụng để cung cấp thêm thông tin nhằm điều chỉnh hoặc tùy chỉnh việc thực hiện chương trình. Trong trường hợp không rõ ràng, các tùy chọn thường là optional. Một chương trình sẽ có thể chạy tốt mà không cần bất kỳ tùy chọn nào. (Chọn một chương trình ngẫu nhiên từ bộ công cụ Unix hoặc GNU. Nó có thể chạy mà không cần bất kỳ tùy chọn nào mà vẫn hợp lý không? Các ngoại lệ chính là find, tar và dd---tất cả đều là những đột biến kỳ quặc đã bị chỉ trích một cách chính đáng vì cú pháp không chuẩn và giao diện khó hiểu.)
Rất nhiều người muốn chương trình của họ có "các tùy chọn bắt buộc". Hãy nghĩ về nó. Nếu bắt buộc thì đó là not optional! Nếu có một phần thông tin mà chương trình của bạn thực sự yêu cầu để chạy thành công thì đó chính là mục đích của các đối số vị trí.
Là một ví dụ về thiết kế giao diện dòng lệnh tốt, hãy xem xét tiện ích cp khiêm tốn để sao chép tệp. Sẽ không có ý nghĩa gì nếu cố gắng sao chép các tập tin mà không cung cấp đích đến và ít nhất một nguồn. Do đó, cp sẽ không thành công nếu bạn chạy nó mà không có đối số. Tuy nhiên, nó có cú pháp linh hoạt, hữu ích và không yêu cầu bất kỳ tùy chọn nào:
cp SOURCE DEST
cp SOURCE ... DEST-DIR
Bạn có thể tiến khá xa chỉ với điều đó. Hầu hết các triển khai cp đều cung cấp một loạt tùy chọn để điều chỉnh chính xác cách sao chép tệp: bạn có thể duy trì chế độ và thời gian sửa đổi, tránh đi theo các liên kết tượng trưng, hỏi trước khi ghi đè các tệp hiện có, v.v. Nhưng không điều nào trong số này làm xao lãng nhiệm vụ cốt lõi của cp, đó là sao chép tệp này sang tệp khác hoặc một số tệp vào thư mục khác.
Lập luận vị trí để làm gì?¶
Đối số vị trí dành cho những mẩu thông tin mà chương trình của bạn chắc chắn yêu cầu để chạy.
Một giao diện người dùng tốt nên có càng ít yêu cầu tuyệt đối càng tốt. Nếu chương trình của bạn yêu cầu 17 mẩu thông tin riêng biệt để chạy thành công thì điều đó không thành vấn đề how bạn nhận được thông tin đó từ người dùng---hầu hết mọi người sẽ bỏ cuộc và bỏ đi trước khi họ chạy chương trình thành công. Điều này áp dụng cho dù giao diện người dùng là dòng lệnh, tệp cấu hình hay GUI: nếu bạn đưa ra nhiều yêu cầu như vậy đối với người dùng của mình, hầu hết họ sẽ từ bỏ.
Tóm lại, hãy cố gắng giảm thiểu lượng thông tin mà người dùng bắt buộc phải cung cấp---sử dụng các giá trị mặc định hợp lý bất cứ khi nào có thể. Tất nhiên, bạn cũng muốn làm cho chương trình của mình linh hoạt một cách hợp lý. Đó là những lựa chọn dành cho. Xin nhắc lại, không thành vấn đề nếu chúng là các mục trong tệp cấu hình, các tiện ích trong hộp thoại "Tùy chọn" của GUI hoặc các tùy chọn dòng lệnh --- bạn triển khai càng nhiều tùy chọn, chương trình của bạn càng linh hoạt hơn và việc triển khai nó càng trở nên phức tạp hơn. Tất nhiên, quá linh hoạt cũng có những hạn chế; quá nhiều tùy chọn có thể khiến người dùng choáng ngợp và khiến mã của bạn khó bảo trì hơn nhiều.
Hướng dẫn¶
Mặc dù optparse khá linh hoạt và mạnh mẽ nhưng nó cũng dễ sử dụng trong hầu hết các trường hợp. Phần này bao gồm các mẫu mã phổ biến cho bất kỳ chương trình dựa trên optparse- nào.
Trước tiên, bạn cần nhập lớp OptionParser; sau đó, ngay từ đầu chương trình chính, hãy tạo một phiên bản OptionParser:
từ nhập optparse OptionParser
...
trình phân tích cú pháp = OptionParser()
Sau đó, bạn có thể bắt đầu xác định các tùy chọn. Cú pháp cơ bản là:
trình phân tích cú pháp.add_option(opt_str, ...,
attr=giá trị, ...)
Mỗi tùy chọn có một hoặc nhiều chuỗi tùy chọn, chẳng hạn như -f hoặc --file và một số thuộc tính tùy chọn cho optparse biết điều gì sẽ xảy ra và phải làm gì khi gặp tùy chọn đó trên dòng lệnh.
Thông thường, mỗi tùy chọn sẽ có một chuỗi tùy chọn ngắn và một chuỗi tùy chọn dài, ví dụ::
Parser.add_option("-f", "--file", ...)
Bạn có thể tự do xác định bao nhiêu chuỗi tùy chọn ngắn và bao nhiêu chuỗi tùy chọn dài tùy thích (bao gồm cả số 0), miễn là tổng thể có ít nhất một chuỗi tùy chọn.
Các chuỗi tùy chọn được chuyển đến OptionParser.add_option() thực sự là các nhãn cho tùy chọn được xác định bởi lệnh gọi đó. Để ngắn gọn, chúng tôi sẽ thường xuyên đề cập đến encountering an option trên dòng lệnh; trên thực tế, optparse gặp option strings và tìm kiếm các lựa chọn từ họ.
Khi tất cả các tùy chọn của bạn đã được xác định, hãy hướng dẫn optparse phân tích dòng lệnh của chương trình của bạn
(tùy chọn, args) = trình phân tích cú pháp.parse_args()
(Nếu muốn, bạn có thể chuyển danh sách đối số tùy chỉnh cho parse_args(), nhưng điều đó hiếm khi cần thiết: theo mặc định, nó sử dụng sys.argv[1:].)
parse_args() trả về hai giá trị:
options, một đối tượng chứa các giá trị cho tất cả các tùy chọn của bạn---ví dụ: nếu--filenhận một đối số chuỗi đơn thìoptions.filesẽ là tên tệp do người dùng cung cấp hoặcNonenếu người dùng không cung cấp tùy chọn đóargs, danh sách các đối số vị trí còn sót lại sau khi phân tích các tùy chọn
Phần hướng dẫn này chỉ bao gồm bốn thuộc tính tùy chọn quan trọng nhất: action, type, dest (destination) và help. Trong số này, action là cơ bản nhất.
Hiểu hành động tùy chọn¶
Các hành động sẽ cho optparse biết phải làm gì khi gặp một tùy chọn trên dòng lệnh. Có một tập hợp hành động cố định được mã hóa cứng thành optparse; thêm hành động mới là chủ đề nâng cao được đề cập trong phần Mở rộng optparse. Hầu hết các hành động đều yêu cầu optparse lưu trữ một giá trị trong một số biến --- ví dụ: lấy một chuỗi từ dòng lệnh và lưu nó vào thuộc tính của options.
Nếu bạn không chỉ định hành động tùy chọn, optparse sẽ mặc định là store.
Hành động của cửa hàng¶
Hành động tùy chọn phổ biến nhất là store, yêu cầu optparse lấy đối số tiếp theo (hoặc phần còn lại của đối số hiện tại), đảm bảo rằng đối số đó thuộc đúng loại và lưu nó vào đích bạn đã chọn.
Ví dụ:
trình phân tích cú pháp.add_option("-f", "--file",
action="store", type="string", dest="filename")
Bây giờ hãy tạo một dòng lệnh giả và yêu cầu optparse phân tích nó
args = ["-f", "foo.txt"]
(tùy chọn, args) = parser.parse_args(args)
Khi optparse nhìn thấy chuỗi tùy chọn -f, nó sẽ sử dụng đối số tiếp theo, foo.txt và lưu nó trong options.filename. Vì vậy, sau lệnh gọi tới parse_args(), options.filename là "foo.txt".
Một số loại tùy chọn khác được optparse hỗ trợ là int và float. Đây là một tùy chọn yêu cầu một đối số nguyên:
parser.add_option("-n", type="int", dest="num")
Lưu ý rằng tùy chọn này không có chuỗi tùy chọn dài, điều này hoàn toàn có thể chấp nhận được. Ngoài ra, không có hành động rõ ràng nào vì mặc định là store.
Hãy phân tích một dòng lệnh giả khác. Lần này, chúng ta sẽ đặt đối số tùy chọn đối lập với tùy chọn: vì -n42 (một đối số) tương đương với -n 42 (hai đối số), nên mã
(tùy chọn, args) = Parser.parse_args(["-n42"])
in(options.num)
sẽ in 42.
Nếu bạn không chỉ định loại, optparse sẽ giả sử string. Kết hợp với thực tế là hành động mặc định là store, điều đó có nghĩa là ví dụ đầu tiên của chúng ta có thể ngắn hơn rất nhiều:
parser.add_option("-f", "--file", dest="filename")
Nếu bạn không cung cấp đích, optparse sẽ tìm ra một mặc định hợp lý từ các chuỗi tùy chọn: nếu chuỗi tùy chọn dài đầu tiên là --foo-bar thì đích mặc định là foo_bar. Nếu không có chuỗi tùy chọn dài, optparse sẽ xem chuỗi tùy chọn ngắn đầu tiên: đích mặc định cho -f là f.
optparse cũng bao gồm loại complex tích hợp sẵn. Việc thêm các loại được đề cập trong phần Mở rộng optparse.
Xử lý các tùy chọn boolean (cờ)¶
Các tùy chọn gắn cờ --- đặt một biến thành đúng hoặc sai khi nhìn thấy một tùy chọn cụ thể --- khá phổ biến. optparse hỗ trợ chúng bằng hai hành động riêng biệt là store_true và store_false. Ví dụ: bạn có thể có cờ verbose được bật bằng -v và tắt bằng -q:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")
Ở đây chúng ta có hai lựa chọn khác nhau với cùng một đích đến, điều này hoàn toàn ổn. (Điều đó chỉ có nghĩa là bạn phải cẩn thận một chút khi đặt giá trị mặc định---xem bên dưới.)
Khi optparse gặp -v trên dòng lệnh, nó đặt options.verbose thành True; khi gặp -q, options.verbose được đặt thành False.
Các hành động khác¶
Một số hành động khác được optparse hỗ trợ là:
"store_const"lưu trữ một giá trị không đổi, được đặt trước qua
Option.const"append"nối đối số của tùy chọn này vào danh sách
"count"tăng bộ đếm lên một
"callback"gọi một hàm được chỉ định
Chúng được trình bày trong phần Hướng dẫn tham khảo và phần Tùy chọn gọi lại.
Giá trị mặc định¶
Tất cả các ví dụ trên đều liên quan đến việc thiết lập một số biến ("đích") khi nhìn thấy các tùy chọn dòng lệnh nhất định. Điều gì xảy ra nếu những lựa chọn đó không bao giờ được nhìn thấy? Vì chúng tôi không cung cấp bất kỳ giá trị mặc định nào nên tất cả chúng đều được đặt thành None. Điều này thường ổn nhưng đôi khi bạn muốn kiểm soát nhiều hơn. optparse cho phép bạn cung cấp giá trị mặc định cho từng đích, giá trị này được chỉ định trước khi dòng lệnh được phân tích cú pháp.
Đầu tiên, hãy xem xét ví dụ dài dòng/im lặng. Nếu chúng ta muốn optparse đặt verbose thành True trừ khi -q được nhìn thấy, thì chúng ta có thể làm điều này:
parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")
Vì các giá trị mặc định áp dụng cho destination thay vì bất kỳ tùy chọn cụ thể nào và hai tùy chọn này có cùng đích đến, nên điều này hoàn toàn tương đương:
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Hãy xem xét điều này:
parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Một lần nữa, giá trị mặc định cho verbose sẽ là True: giá trị mặc định cuối cùng được cung cấp cho bất kỳ đích cụ thể nào là giá trị được tính.
Một cách rõ ràng hơn để chỉ định các giá trị mặc định là phương thức set_defaults() của OptionParser, bạn có thể gọi bất kỳ lúc nào trước khi gọi parse_args():
trình phân tích cú pháp.set_defaults(verbose=True)
trình phân tích cú pháp.add_option(...)
(tùy chọn, args) = trình phân tích cú pháp.parse_args()
Như trước đây, giá trị cuối cùng được chỉ định cho đích tùy chọn nhất định là giá trị được tính. Để rõ ràng, hãy thử sử dụng phương pháp này hoặc phương pháp khác để đặt giá trị mặc định, không phải cả hai.
Tạo trợ giúp¶
Khả năng tự động tạo văn bản trợ giúp và cách sử dụng của optparse rất hữu ích để tạo giao diện dòng lệnh thân thiện với người dùng. Tất cả những gì bạn phải làm là cung cấp giá trị help cho mỗi tùy chọn và tùy chọn một thông báo sử dụng ngắn cho toàn bộ chương trình của bạn. Đây là OptionParser có các tùy chọn (được ghi lại) thân thiện với người dùng
cách sử dụng = "cách sử dụng: %prog [tùy chọn] arg1 arg2"
trình phân tích cú pháp = OptionParser(cách sử dụng=cách sử dụng)
trình phân tích cú pháp.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=True,
help="gây ra nhiều tiếng ồn [mặc định]")
trình phân tích cú pháp.add_option("-q", "--quiet",
hành động="store_false", dest="verbose",
help="im lặng chút đi (Tôi đang săn thỏ)")
trình phân tích cú pháp.add_option("-f", "--filename",
metavar="FILE", help="ghi đầu ra vào FILE")
trình phân tích cú pháp.add_option("-m", "--mode",
mặc định="trung gian",
help="chế độ tương tác: người mới, trung cấp, "
"hoặc chuyên gia [mặc định: %mặc định]")
Nếu optparse gặp -h hoặc --help trên dòng lệnh hoặc nếu bạn chỉ gọi parser.print_help(), nó sẽ in thông tin sau ra đầu ra tiêu chuẩn:
Cách sử dụng: <yourscript> [tùy chọn] arg1 arg2
Tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbose tạo ra nhiều tiếng ồn [mặc định]
-q, --quiet im lặng đi (Tôi đang săn thỏ)
-f FILE, --filename=FILE
ghi đầu ra vào FILE
-m MODE, --mode=MODE chế độ tương tác: người mới, người trung cấp hoặc
chuyên gia [mặc định: trung cấp]
(Nếu đầu ra trợ giúp được kích hoạt bởi tùy chọn trợ giúp, optparse sẽ thoát sau khi in văn bản trợ giúp.)
Có rất nhiều điều đang diễn ra ở đây để giúp optparse tạo ra thông báo trợ giúp tốt nhất có thể:
tập lệnh xác định thông báo sử dụng của riêng nó:
cách sử dụng = "cách sử dụng: %prog [tùy chọn] arg1 arg2"
optparsemở rộng%progtrong chuỗi sử dụng thành tên của chương trình hiện tại, tức làos.path.basename(sys.argv[0]). Sau đó, chuỗi mở rộng sẽ được in trước khi có trợ giúp tùy chọn chi tiết.Nếu bạn không cung cấp chuỗi sử dụng,
optparsesẽ sử dụng một giá trị mặc định nhạt nhẽo nhưng hợp lý:"Usage: %prog [options]", điều này sẽ ổn nếu tập lệnh của bạn không nhận bất kỳ đối số vị trí nào.mọi tùy chọn đều xác định một chuỗi trợ giúp và không phải lo lắng về việc ngắt dòng---
optparseđảm nhiệm việc gói các dòng và làm cho đầu ra trợ giúp trông đẹp mắt.các tùy chọn nhận giá trị cho biết thực tế này trong thông báo trợ giúp được tạo tự động, ví dụ: cho tùy chọn "chế độ":
-m MODE, --mode=MODE
Ở đây, "MODE" được gọi là biến meta: nó đại diện cho đối số mà người dùng dự kiến sẽ cung cấp cho
-m/--mode. Theo mặc định,optparsechuyển đổi tên biến đích thành chữ hoa và sử dụng tên đó cho biến meta. Đôi khi, đó không phải là điều bạn muốn---ví dụ: tùy chọn--filenameđặtmetavar="FILE"một cách rõ ràng, dẫn đến mô tả tùy chọn được tạo tự động này:-f FILE, --filename=FILE
Tuy nhiên, điều này quan trọng không chỉ để tiết kiệm dung lượng: văn bản trợ giúp được viết thủ công sử dụng biến meta
FILEđể gợi ý cho người dùng rằng có mối liên hệ giữa cú pháp bán chính thức-f FILEvà mô tả ngữ nghĩa không chính thức "ghi đầu ra vào FILE". Đây là một cách đơn giản nhưng hiệu quả để làm cho văn bản trợ giúp của bạn rõ ràng hơn và hữu ích hơn cho người dùng cuối.các tùy chọn có giá trị mặc định có thể bao gồm
%defaulttrong chuỗi trợ giúp---optparsesẽ thay thế nó bằngstr()giá trị mặc định của tùy chọn. Nếu một tùy chọn không có giá trị mặc định (hoặc giá trị mặc định làNone),%defaultsẽ mở rộng thànhnone.
Tùy chọn nhóm¶
Khi xử lý nhiều tùy chọn, sẽ thuận tiện hơn khi nhóm các tùy chọn này để có kết quả trợ giúp tốt hơn. Một OptionParser có thể chứa một số nhóm tùy chọn, mỗi nhóm có thể chứa một số tùy chọn.
Một nhóm tùy chọn thu được bằng cách sử dụng lớp OptionGroup:
- class optparse.OptionGroup(parser, title, description=None)¶
ở đâu
trình phân tích cú pháp là phiên bản
OptionParsermà nhóm sẽ được chèn vàotitle là tên nhóm
mô tả, tùy chọn, là một mô tả dài về nhóm
OptionGroup kế thừa từ OptionContainer (như OptionParser) và do đó phương thức add_option() có thể được sử dụng để thêm tùy chọn vào nhóm.
Khi tất cả các tùy chọn được khai báo, sử dụng phương thức OptionParser add_option_group(), nhóm sẽ được thêm vào trình phân tích cú pháp được xác định trước đó.
Tiếp tục với trình phân tích cú pháp được xác định trong phần trước, việc thêm OptionGroup vào trình phân tích cú pháp thật dễ dàng:
group = OptionGroup(trình phân tích cú pháp, "Tùy chọn nguy hiểm",
"Thận trọng: bạn phải tự chịu rủi ro khi sử dụng các tùy chọn này."
"Người ta tin rằng một số trong số chúng đã cắn.")
group.add_option("-g", action="store_true", help="Tùy chọn nhóm.")
trình phân tích cú pháp.add_option_group(nhóm)
Điều này sẽ dẫn đến kết quả trợ giúp sau:
Cách sử dụng: <yourscript> [tùy chọn] arg1 arg2
Tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbose tạo ra nhiều tiếng ồn [mặc định]
-q, --quiet im lặng đi (Tôi đang săn thỏ)
-f FILE, --filename=FILE
ghi đầu ra vào FILE
-m MODE, --mode=MODE chế độ tương tác: người mới, người trung cấp hoặc
chuyên gia [mặc định: trung cấp]
Tùy chọn nguy hiểm:
Thận trọng: sử dụng các tùy chọn này có nguy cơ của riêng bạn. Người ta tin rằng một số
trong số chúng cắn.
-g Tùy chọn nhóm.
Một ví dụ đầy đủ hơn một chút có thể liên quan đến việc sử dụng nhiều hơn một nhóm: vẫn mở rộng ví dụ trước:
group = OptionGroup(trình phân tích cú pháp, "Tùy chọn nguy hiểm",
"Thận trọng: bạn phải tự chịu rủi ro khi sử dụng các tùy chọn này."
"Người ta tin rằng một số trong số chúng đã cắn.")
group.add_option("-g", action="store_true", help="Tùy chọn nhóm.")
trình phân tích cú pháp.add_option_group(nhóm)
group = OptionGroup(trình phân tích cú pháp, "Tùy chọn gỡ lỗi")
group.add_option("-d", "--debug", action="store_true",
help="In thông tin gỡ lỗi")
group.add_option("-s", "--sql", action="store_true",
help="In tất cả các câu lệnh SQL đã thực thi")
group.add_option("-e", action="store_true", help="In mọi hành động đã thực hiện")
trình phân tích cú pháp.add_option_group(nhóm)
dẫn đến kết quả đầu ra sau:
Cách sử dụng: <yourscript> [tùy chọn] arg1 arg2
Tùy chọn:
-h, --help hiển thị thông báo trợ giúp này và thoát
-v, --verbose tạo ra nhiều tiếng ồn [mặc định]
-q, --quiet im lặng đi (Tôi đang săn thỏ)
-f FILE, --filename=FILE
ghi đầu ra vào FILE
-m MODE, --mode=MODE chế độ tương tác: người mới, người trung cấp hoặc chuyên gia
[mặc định: trung gian]
Tùy chọn nguy hiểm:
Thận trọng: sử dụng các tùy chọn này có nguy cơ của riêng bạn. Người ta tin rằng một số
trong số chúng cắn.
-g Tùy chọn nhóm.
Tùy chọn gỡ lỗi:
-d, --debug In thông tin gỡ lỗi
-s, --sql In tất cả các câu lệnh SQL được thực thi
-e In mọi hành động được thực hiện
Một phương pháp thú vị khác, đặc biệt khi làm việc theo chương trình với các nhóm tùy chọn là:
- OptionParser.get_option_group(opt_str)¶
Trả về
OptionGroupchứa chuỗi tùy chọn ngắn hoặc dài opt_str (ví dụ:'-o'hoặc'--option'). Nếu không cóOptionGroupnhư vậy, hãy trả vềNone.
In chuỗi phiên bản¶
Tương tự như chuỗi sử dụng ngắn gọn, optparse cũng có thể in chuỗi phiên bản cho chương trình của bạn. Bạn phải cung cấp chuỗi làm đối số version cho OptionParser:
trình phân tích cú pháp = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
%prog được mở rộng giống như trong usage. Ngoài ra, version có thể chứa bất cứ thứ gì bạn thích. Khi bạn cung cấp nó, optparse sẽ tự động thêm tùy chọn --version vào trình phân tích cú pháp của bạn. Nếu nó gặp tùy chọn này trên dòng lệnh, nó sẽ mở rộng chuỗi version của bạn (bằng cách thay thế %prog), in nó ra thiết bị xuất chuẩn và thoát.
Ví dụ: nếu tập lệnh của bạn có tên là /usr/bin/foo:
$ /usr/bin/foo --version
foo 1.0
Hai phương pháp sau đây có thể được sử dụng để in và lấy chuỗi version:
- OptionParser.print_version(file=None)¶
In thông báo phiên bản cho chương trình hiện tại (
self.version) thành file (thiết bị xuất chuẩn mặc định). Giống nhưprint_usage(), bất kỳ sự xuất hiện nào của%progtrongself.versionđều được thay thế bằng tên của chương trình hiện tại. Không có gì nếuself.versiontrống hoặc không xác định.
- OptionParser.get_version()¶
Tương tự như
print_version()nhưng trả về chuỗi phiên bản thay vì in ra.
Cách optparse xử lý lỗi¶
Có hai loại lỗi lớn mà optparse phải lo lắng: lỗi lập trình viên và lỗi người dùng. Lỗi lập trình viên thường là các lệnh gọi sai tới OptionParser.add_option(), ví dụ: chuỗi tùy chọn không hợp lệ, thuộc tính tùy chọn không xác định, thuộc tính tùy chọn bị thiếu, v.v. Chúng được xử lý theo cách thông thường: đưa ra một ngoại lệ (optparse.OptionError hoặc TypeError) và khiến chương trình gặp sự cố.
Xử lý lỗi của người dùng quan trọng hơn nhiều vì chúng chắc chắn sẽ xảy ra cho dù mã của bạn có ổn định đến đâu. optparse có thể tự động phát hiện một số lỗi của người dùng, chẳng hạn như đối số tùy chọn không hợp lệ (chuyển -n 4x trong đó -n nhận đối số nguyên), thiếu đối số (-n ở cuối dòng lệnh, trong đó -n nhận đối số thuộc bất kỳ loại nào). Ngoài ra, bạn có thể gọi OptionParser.error() để báo hiệu tình trạng lỗi do ứng dụng xác định
(tùy chọn, args) = trình phân tích cú pháp.parse_args()
...
nếu tùy chọn.a và tùy chọn.b:
Parser.error("các tùy chọn -a và -b loại trừ lẫn nhau")
Trong cả hai trường hợp, optparse xử lý lỗi theo cùng một cách: nó in thông báo sử dụng của chương trình và thông báo lỗi thành lỗi tiêu chuẩn và thoát với trạng thái lỗi 2.
Hãy xem xét ví dụ đầu tiên ở trên, trong đó người dùng chuyển 4x đến một tùy chọn lấy số nguyên:
$ /usr/bin/foo -n 4x
Cách sử dụng: foo [tùy chọn]
foo: error: option -n: giá trị nguyên không hợp lệ: '4x'
Hoặc, khi người dùng không chuyển được một giá trị nào:
$ /usr/bin/foo -n
Cách sử dụng: foo [tùy chọn]
foo: error: tùy chọn -n yêu cầu một đối số
optparse-thông báo lỗi được tạo ra, hãy luôn đề cập đến tùy chọn liên quan đến lỗi; hãy nhớ thực hiện tương tự khi gọi OptionParser.error() từ mã ứng dụng của bạn.
Nếu hành vi xử lý lỗi mặc định của optparse không phù hợp với nhu cầu của bạn, bạn sẽ cần phải phân lớp OptionParser và ghi đè các phương thức exit() và/hoặc error() của nó.
Đặt tất cả lại với nhau¶
Đây là các tập lệnh dựa trên optparse- thường trông như thế nào:
từ nhập optparse OptionParser
...
chắc chắn chính():
cách sử dụng = "cách sử dụng:% prog [tùy chọn] arg"
trình phân tích cú pháp = OptionParser(cách sử dụng)
parser.add_option("-f", "--file", dest="filename",
help="đọc dữ liệu từ FILENAME")
trình phân tích cú pháp.add_option("-v", "--verbose",
hành động="store_true", dest="verbose")
trình phân tích cú pháp.add_option("-q", "--quiet",
hành động="store_false", dest="verbose")
...
(tùy chọn, args) = trình phân tích cú pháp.parse_args()
nếu len(args) != 1:
Parser.error("số lượng đối số không chính xác")
nếu tùy chọn.verbose:
print("Đang đọc %s..." % options.filename)
...
nếu __name__ == "__main__":
chính()
Hướng dẫn tham khảo¶
Tạo trình phân tích cú pháp¶
Bước đầu tiên khi sử dụng optparse là tạo một phiên bản OptionParser.
- class optparse.OptionParser(...)¶
Hàm tạo OptionParser không có đối số bắt buộc nhưng có một số đối số từ khóa tùy chọn. Bạn phải luôn chuyển chúng dưới dạng đối số từ khóa, tức là không dựa vào thứ tự khai báo đối số.
usage(mặc định:"%prog [options]")Bản tóm tắt sử dụng để in khi chương trình của bạn chạy không chính xác hoặc có tùy chọn trợ giúp. Khi
optparsein chuỗi sử dụng, nó sẽ mở rộng%progthànhos.path.basename(sys.argv[0])(hoặc thànhprognếu bạn chuyển đối số từ khóa đó). Để chặn thông báo sử dụng, hãy chuyển giá trị đặc biệtoptparse.SUPPRESS_USAGE.option_list(mặc định:[])Danh sách các đối tượng Tùy chọn để điền vào trình phân tích cú pháp. Các tùy chọn trong
option_listđược thêm vào sau bất kỳ tùy chọn nào trongstandard_option_list(thuộc tính lớp có thể được đặt bởi các lớp con OptionParser), nhưng trước bất kỳ phiên bản hoặc tùy chọn trợ giúp nào. Không dùng nữa; thay vào đó hãy sử dụngadd_option()sau khi tạo trình phân tích cú pháp.option_class(mặc định: optparse.Option)Lớp sử dụng khi thêm tùy chọn vào trình phân tích cú pháp trong
add_option().version(mặc định:None)Chuỗi phiên bản để in khi người dùng cung cấp tùy chọn phiên bản. Nếu bạn cung cấp giá trị thực cho
version,optparsesẽ tự động thêm tùy chọn phiên bản với chuỗi tùy chọn duy nhất--version. Chuỗi con%progđược mở rộng giống như chuỗiusage.conflict_handler(mặc định:"error")Chỉ định những việc cần làm khi các tùy chọn có chuỗi tùy chọn xung đột được thêm vào trình phân tích cú pháp; xem phần Xung đột giữa các lựa chọn.
description(mặc định:None)Một đoạn văn bản cung cấp một cái nhìn tổng quan ngắn gọn về chương trình của bạn.
optparseđịnh dạng lại đoạn này để vừa với chiều rộng của thiết bị đầu cuối hiện tại và in nó khi người dùng yêu cầu trợ giúp (sauusage, nhưng trước danh sách tùy chọn).formatter(mặc định:IndentedHelpFormattermới)Một phiên bản optparse.HelpFormatter sẽ được sử dụng để in văn bản trợ giúp.
optparsecung cấp hai lớp cụ thể cho mục đích này: IndentedHelpFormatter và TitledHelpFormatter.add_help_option(mặc định:True)Nếu đúng,
optparsesẽ thêm tùy chọn trợ giúp (với chuỗi tùy chọn-hvà--help) vào trình phân tích cú pháp.progChuỗi sử dụng khi mở rộng
%progtrongusagevàversionthay vìos.path.basename(sys.argv[0]).epilog(mặc định:None)Một đoạn văn bản trợ giúp sẽ được in sau tùy chọn trợ giúp.
Điền trình phân tích cú pháp¶
Có một số cách để đưa vào trình phân tích cú pháp các tùy chọn. Cách tốt nhất là sử dụng OptionParser.add_option(), như được trình bày trong phần Hướng dẫn. add_option() có thể được gọi theo một trong hai cách:
chuyển cho nó một phiên bản Tùy chọn (được trả về bởi
make_option())chuyển cho nó bất kỳ sự kết hợp nào giữa các đối số vị trí và từ khóa được chấp nhận bởi
make_option()(tức là đối với hàm tạo Tùy chọn) và nó sẽ tạo phiên bản Tùy chọn cho bạn
Cách khác là chuyển danh sách các phiên bản Tùy chọn được tạo sẵn cho hàm tạo OptionParser, như trong
tùy chọn_list = [
make_option("-f", "--filename",
action="store", type="string", dest="filename"),
make_option("-q", "--quiet",
hành động="store_false", dest="verbose"),
]
trình phân tích cú pháp = OptionParser(option_list=option_list)
(make_option() là một hàm gốc để tạo các phiên bản Tùy chọn; hiện tại nó là bí danh của hàm tạo Tùy chọn. Phiên bản trong tương lai của optparse có thể chia Tùy chọn thành nhiều lớp và make_option() sẽ chọn đúng lớp để khởi tạo. Không khởi tạo Tùy chọn trực tiếp.)
Xác định các tùy chọn¶
Mỗi phiên bản Tùy chọn đại diện cho một tập hợp các chuỗi tùy chọn dòng lệnh đồng nghĩa, ví dụ: -f và --file. Bạn có thể chỉ định số lượng chuỗi tùy chọn ngắn hoặc dài bất kỳ, nhưng bạn phải chỉ định ít nhất một chuỗi tùy chọn tổng thể.
Cách chuẩn để tạo một phiên bản Option là sử dụng phương thức add_option() của OptionParser.
- OptionParser.add_option(option)¶
- OptionParser.add_option(*opt_str, attr=value, ...)
Để xác định một tùy chọn chỉ có một chuỗi tùy chọn ngắn
parser.add_option("-f", attr=value, ...)
Và để xác định một tùy chọn chỉ có một chuỗi tùy chọn dài
parser.add_option("--foo", attr=value, ...)
Các đối số từ khóa xác định các thuộc tính của đối tượng Tùy chọn mới. Thuộc tính tùy chọn quan trọng nhất là
actionvà nó quyết định phần lớn những thuộc tính nào khác có liên quan hoặc bắt buộc. Nếu bạn chuyển các thuộc tính tùy chọn không liên quan hoặc không chuyển các thuộc tính bắt buộc,optparsesẽ đưa ra một ngoại lệOptionErrorgiải thích lỗi của bạn.action của một tùy chọn xác định
optparsesẽ làm gì khi gặp tùy chọn này trên dòng lệnh. Các hành động tùy chọn tiêu chuẩn được mã hóa cứng vàooptparselà:"store"lưu trữ đối số của tùy chọn này (mặc định)
"store_const"lưu trữ một giá trị không đổi, được đặt trước qua
Option.const"store_true"cửa hàng
True"store_false"cửa hàng
False"append"nối đối số của tùy chọn này vào danh sách
"append_const"thêm một giá trị không đổi vào danh sách, được đặt trước qua
Option.const"count"tăng bộ đếm lên một
"callback"gọi một hàm được chỉ định
"help"in thông báo sử dụng bao gồm tất cả các tùy chọn và tài liệu cho chúng
(Nếu bạn không cung cấp một hành động thì mặc định là
"store". Đối với hành động này, bạn cũng có thể cung cấp các thuộc tính tùy chọntypevàdest; xem Hành động tùy chọn tiêu chuẩn.)
Như bạn có thể thấy, hầu hết các hành động đều liên quan đến việc lưu trữ hoặc cập nhật một giá trị ở đâu đó. optparse luôn tạo một đối tượng đặc biệt cho việc này, thường được gọi là options, một phiên bản của optparse.Values.
- class optparse.Values¶
Một đối tượng chứa tên và giá trị đối số được phân tích cú pháp làm thuộc tính. Thường được tạo bằng cách gọi khi gọi
OptionParser.parse_args()và có thể bị ghi đè bởi một lớp con tùy chỉnh được truyền cho đối số values củaOptionParser.parse_args()(như được mô tả trong Phân tích đối số).
Các đối số tùy chọn (và nhiều giá trị khác) được lưu trữ dưới dạng thuộc tính của đối tượng này, theo thuộc tính tùy chọn dest (đích).
Ví dụ: khi bạn gọi
trình phân tích cú pháp.parse_args()
một trong những điều đầu tiên optparse thực hiện là tạo đối tượng options:
tùy chọn = Giá trị()
Nếu một trong các tùy chọn trong trình phân tích cú pháp này được xác định bằng
Parser.add_option("-f", "--file", action="store", type="string", dest="filename")
và dòng lệnh được phân tích cú pháp bao gồm bất kỳ thông tin nào sau đây
-ffoo
-f foo
--file=foo
--file foo
thì optparse, khi nhìn thấy tùy chọn này, sẽ thực hiện tương đương với
options.filename = "foo"
Các thuộc tính tùy chọn type và dest gần như quan trọng như action, nhưng action là thuộc tính duy nhất có ý nghĩa đối với các tùy chọn all.
Thuộc tính tùy chọn¶
- class optparse.Option¶
Một đối số dòng lệnh duy nhất, với các thuộc tính khác nhau được truyền từ khóa tới hàm tạo. Thường được tạo bằng
OptionParser.add_option()chứ không phải trực tiếp và có thể được ghi đè bởi một lớp tùy chỉnh thông qua đối số option_class thànhOptionParser.
Các thuộc tính tùy chọn sau đây có thể được chuyển dưới dạng đối số từ khóa cho OptionParser.add_option(). Nếu bạn chuyển một thuộc tính tùy chọn không liên quan đến một tùy chọn cụ thể hoặc không chuyển thuộc tính tùy chọn bắt buộc, optparse sẽ tăng OptionError.
- Option.action¶
(mặc định:
"store")Xác định hành vi của
optparsekhi tùy chọn này được nhìn thấy trên dòng lệnh; các tùy chọn có sẵn được ghi lại here.
- Option.type¶
(mặc định:
"string")Loại đối số mà tùy chọn này mong đợi (ví dụ:
"string"hoặc"int"); các loại tùy chọn có sẵn được ghi lại here.
- Option.dest¶
(mặc định: xuất phát từ chuỗi tùy chọn)
Nếu hành động của tùy chọn ngụ ý ghi hoặc sửa đổi một giá trị ở đâu đó, điều này sẽ cho
optparsebiết nơi ghi giá trị đó:destđặt tên cho một thuộc tính của đối tượngoptionsmàoptparsexây dựng khi nó phân tích dòng lệnh.
- Option.default¶
Giá trị sử dụng cho đích của tùy chọn này nếu tùy chọn này không được nhìn thấy trên dòng lệnh. Xem thêm
OptionParser.set_defaults().
- Option.nargs¶
(mặc định: 1)
Cần sử dụng bao nhiêu đối số thuộc loại
typekhi nhìn thấy tùy chọn này. Nếu > 1,optparsesẽ lưu trữ một bộ giá trị vàodest.
- Option.const¶
Đối với các hành động lưu trữ một giá trị không đổi, giá trị không đổi cần lưu trữ.
- Option.choices¶
Đối với các tùy chọn loại
"choice", danh sách các chuỗi mà người dùng có thể chọn.
- Option.callback¶
Đối với các tùy chọn có hành động
"callback", có thể gọi khi tùy chọn này được nhìn thấy. Xem phần Tùy chọn gọi lại để biết chi tiết về các đối số được truyền cho đối tượng có thể gọi được.
- Option.callback_args¶
- Option.callback_kwargs¶
Các đối số từ khóa và vị trí bổ sung cần chuyển tới
callbacksau bốn đối số gọi lại tiêu chuẩn.
- Option.help¶
Văn bản trợ giúp in cho tùy chọn này khi liệt kê tất cả các tùy chọn có sẵn sau khi người dùng cung cấp tùy chọn
help(chẳng hạn như--help). Nếu không có văn bản trợ giúp nào được cung cấp, tùy chọn sẽ được liệt kê mà không có văn bản trợ giúp. Để ẩn tùy chọn này, hãy sử dụng giá trị đặc biệtoptparse.SUPPRESS_HELP.
Hành động tùy chọn tiêu chuẩn¶
Các hành động tùy chọn khác nhau đều có các yêu cầu và tác dụng hơi khác nhau. Hầu hết các hành động đều có một số thuộc tính tùy chọn liên quan mà bạn có thể chỉ định để hướng dẫn hành vi của optparse; một số có các thuộc tính bắt buộc mà bạn phải chỉ định cho bất kỳ tùy chọn nào sử dụng hành động đó.
"store"[có liên quan:type,dest,nargs,choices]Theo sau tùy chọn này phải là một đối số, đối số này được chuyển đổi thành giá trị theo
typevà được lưu trữ trongdest. Nếunargs> 1, nhiều đối số sẽ được sử dụng từ dòng lệnh; tất cả sẽ được chuyển đổi theotypevà được lưu trữ thànhdestdưới dạng tuple. Xem phần Các loại tùy chọn tiêu chuẩn.Nếu
choicesđược cung cấp (danh sách hoặc bộ chuỗi), loại mặc định là"choice".Nếu
typekhông được cung cấp, nó sẽ mặc định là"string".Nếu
destkhông được cung cấp,optparsesẽ lấy đích từ chuỗi tùy chọn dài đầu tiên (ví dụ:--foo-barngụ ýfoo_bar). Nếu không có chuỗi tùy chọn dài,optparsesẽ lấy đích từ chuỗi tùy chọn ngắn đầu tiên (ví dụ:-fngụ ýf).Ví dụ:
trình phân tích cú pháp.add_option("-f") parser.add_option("-p", type="float", nargs=3, dest="point")
Khi nó phân tích dòng lệnh
-f foo.txt -p 1 -3.5 4 -fbar.txt
optparsesẽ đặttùy chọn.f = "foo.txt" tùy chọn.point = (1.0, -3.5, 4.0) tùy chọn.f = "bar.txt"
"store_const"[bắt buộc:const; có liên quan:dest]Giá trị
constđược lưu trữ trongdest.Ví dụ:
trình phân tích cú pháp.add_option("-q", "--quiet", hành động="store_const", const=0, dest="verbose") trình phân tích cú pháp.add_option("-v", "--verbose", hành động="store_const", const=1, dest="verbose") parser.add_option("--noisy", hành động="store_const", const=2, dest="verbose")
Nếu
--noisyđược nhìn thấy,optparsesẽ đặttùy chọn.verbose = 2
"store_true"[có liên quan:dest]Một trường hợp đặc biệt của
"store_const"lưu trữTrueđếndest."store_false"[có liên quan:dest]Giống như
"store_true"nhưng lưu trữFalse.Ví dụ:
parser.add_option("--clobber", action="store_true", dest="clobber") parser.add_option("--no-clobber", action="store_false", dest="clobber")
"append"[có liên quan:type,dest,nargs,choices]Theo sau tùy chọn này phải là một đối số, được thêm vào danh sách trong
dest. Nếu không có giá trị mặc định nào chodestđược cung cấp, một danh sách trống sẽ tự động được tạo khioptparsegặp tùy chọn này lần đầu trên dòng lệnh. Nếunargs> 1, nhiều đối số sẽ được sử dụng và một bộ có độ dàinargssẽ được thêm vàodest.Giá trị mặc định cho
typevàdestgiống như đối với hành động"store".Ví dụ:
Parser.add_option("-t", "--tracks", action="append", type="int")
Nếu
-t3được nhìn thấy trên dòng lệnh,optparsethực hiện tương đương vớitùy chọn.tracks = [] tùy chọn.tracks.append(int("3"))
Nếu sau đó một lát,
--tracks=4được nhìn thấy, thì nó sẽtùy chọn.tracks.append(int("4"))
Hành động
appendgọi phương thứcappendtrên giá trị hiện tại của tùy chọn. Điều này có nghĩa là bất kỳ giá trị mặc định nào được chỉ định đều phải có phương thứcappend. Điều đó cũng có nghĩa là nếu giá trị mặc định không trống thì các phần tử mặc định sẽ xuất hiện trong giá trị được phân tích cú pháp cho tùy chọn, với mọi giá trị từ dòng lệnh được thêm vào sau các giá trị mặc định đó:>>> Parser.add_option("--files", action="append", default=['~/.mypkg/defaults']) >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg']) >>> opts.files ['~/.mypkg/defaults', 'overrides.mypkg']
"append_const"[bắt buộc:const; có liên quan:dest]Giống như
"store_const", nhưng giá trịconstđược thêm vàodest; như với"append",destmặc định làNonevà một danh sách trống sẽ tự động được tạo khi gặp tùy chọn này lần đầu tiên."count"[có liên quan:dest]Tăng số nguyên được lưu trữ tại
dest. Nếu không có giá trị mặc định nào được cung cấp,destđược đặt thành 0 trước khi tăng lần đầu tiên.Ví dụ:
parser.add_option("-v", action="count", dest="verbosity")
Lần đầu tiên
-vđược nhìn thấy trên dòng lệnh,optparsethực hiện tương đương vớitùy chọn.verbosity = 0 tùy chọn.verbosity += 1
Mỗi lần xuất hiện tiếp theo của
-vđều dẫn đếntùy chọn.verbosity += 1
"callback"[bắt buộc:callback; có liên quan:type,nargs,callback_args,callback_kwargs]Gọi hàm do
callbackchỉ định, hàm này được gọi làfunc(tùy chọn, opt_str, giá trị, trình phân tích cú pháp, *args, **kwargs)
Xem phần Tùy chọn gọi lại để biết thêm chi tiết.
"help"In thông báo trợ giúp hoàn chỉnh cho tất cả các tùy chọn trong trình phân tích cú pháp tùy chọn hiện tại. Thông báo trợ giúp được tạo từ chuỗi
usageđược truyền tới hàm tạo của OptionParser và chuỗihelpđược truyền cho mọi tùy chọn.Nếu không có chuỗi
helpnào được cung cấp cho một tùy chọn, nó vẫn sẽ được liệt kê trong thông báo trợ giúp. Để bỏ qua hoàn toàn một tùy chọn, hãy sử dụng giá trị đặc biệtoptparse.SUPPRESS_HELP.optparsetự động thêm tùy chọnhelpcho tất cả các OptionParsers, vì vậy thông thường bạn không cần phải tạo một tùy chọn.Ví dụ:
từ nhập optparse OptionParser, SUPPRESS_HELP # usually, một tùy chọn trợ giúp sẽ được thêm tự động, nhưng điều đó có thể # be bị chặn bằng cách sử dụng đối số add_help_option trình phân tích cú pháp = OptionParser(add_help_option=False) parser.add_option("-h", "--help", action="help") parser.add_option("-v", action="store_true", dest="verbose", help="Nói dài vừa phải") parser.add_option("--file", dest="filename", help="Nhập tệp để đọc dữ liệu từ") parser.add_option("--secret", help=SUPPRESS_HELP)
Nếu
optparsethấy-hhoặc--helptrên dòng lệnh, nó sẽ in nội dung giống như thông báo trợ giúp sau tới thiết bị xuất chuẩn (giả sửsys.argv[0]là"foo.py"):Cách sử dụng: foo.py [tùy chọn] Tùy chọn: -h, --help Hiển thị thông báo trợ giúp này và thoát -v Hãy dài dòng vừa phải --file=FILENAME Tệp đầu vào để đọc dữ liệu từ
Sau khi in thông báo trợ giúp,
optparsesẽ kết thúc quá trình của bạn vớisys.exit(0)."version"In số phiên bản được cung cấp cho OptionParser thành thiết bị xuất chuẩn và thoát. Số phiên bản thực sự được định dạng và in bằng phương pháp
print_version()của OptionParser. Nói chung chỉ có liên quan nếu đối sốversionđược cung cấp cho hàm tạo OptionParser. Giống như các tùy chọnhelp, bạn sẽ hiếm khi tạo các tùy chọnversion, vìoptparsetự động thêm chúng khi cần.
Các loại tùy chọn tiêu chuẩn¶
optparse có năm loại tùy chọn tích hợp: "string", "int", "choice", "float" và "complex". Nếu bạn cần thêm các loại tùy chọn mới, hãy xem phần Mở rộng optparse.
Các đối số cho các tùy chọn chuỗi không được kiểm tra hoặc chuyển đổi theo bất kỳ cách nào: văn bản trên dòng lệnh được lưu trữ ở đích (hoặc được chuyển đến cuộc gọi lại).
Đối số nguyên (loại "int") được phân tích cú pháp như sau:
nếu số bắt đầu bằng
0x, nó sẽ được phân tích cú pháp dưới dạng số thập lục phânnếu số bắt đầu bằng
0, nó sẽ được phân tích cú pháp dưới dạng số bát phânnếu số bắt đầu bằng
0b, nó sẽ được phân tích cú pháp dưới dạng số nhị phânmặt khác, số được phân tích cú pháp dưới dạng số thập phân
Việc chuyển đổi được thực hiện bằng cách gọi int() với cơ số thích hợp (2, 8, 10 hoặc 16). Nếu điều này không thành công thì optparse cũng vậy, mặc dù có thông báo lỗi hữu ích hơn.
Các đối số tùy chọn "float" và "complex" được chuyển đổi trực tiếp bằng float() và complex(), với cách xử lý lỗi tương tự.
Tùy chọn "choice" là một loại phụ của tùy chọn "string". Thuộc tính tùy chọn choices (một chuỗi các chuỗi) xác định tập hợp các đối số tùy chọn được phép. optparse.check_choice() so sánh các đối số tùy chọn do người dùng cung cấp với danh sách chính này và tăng OptionValueError nếu đưa ra một chuỗi không hợp lệ.
Phân tích đối số¶
Toàn bộ mục đích của việc tạo và điền OptionParser là gọi phương thức parse_args() của nó.
- OptionParser.parse_args(args=None, values=None)¶
Phân tích các tùy chọn dòng lệnh có trong args.
Các thông số đầu vào là
argsdanh sách các đối số cần xử lý (mặc định:
sys.argv[1:])valuesmột đối tượng
Valuesđể lưu trữ các đối số tùy chọn trong (mặc định: một phiên bản mới củaValues) -- nếu bạn cung cấp một đối tượng hiện có, các giá trị mặc định của tùy chọn sẽ không được khởi tạo trên nó
và giá trị trả về là một cặp
(options, args)trong đóoptionscùng một đối tượng được truyền vào dưới dạng values hoặc phiên bản
optparse.Valuesđược tạo bởioptparseargscác đối số vị trí còn sót lại sau khi tất cả các tùy chọn đã được xử lý
Cách sử dụng phổ biến nhất là không cung cấp đối số từ khóa. Nếu bạn cung cấp values, nó sẽ được sửa đổi bằng các lệnh gọi setattr() lặp đi lặp lại (khoảng một lệnh cho mỗi đối số tùy chọn được lưu trữ đến đích tùy chọn) và được trả về bởi parse_args().
Nếu parse_args() gặp bất kỳ lỗi nào trong danh sách đối số, nó sẽ gọi phương thức error() của OptionParser kèm theo thông báo lỗi thích hợp cho người dùng cuối. Điều này cuối cùng sẽ chấm dứt quá trình của bạn với trạng thái thoát là 2 (trạng thái thoát Unix truyền thống đối với các lỗi dòng lệnh).
Truy vấn và thao tác trình phân tích cú pháp tùy chọn của bạn¶
Hành vi mặc định của trình phân tích cú pháp tùy chọn có thể được tùy chỉnh một chút và bạn cũng có thể xem xét trình phân tích cú pháp tùy chọn của mình và xem những gì ở đó. OptionParser cung cấp một số phương pháp để giúp bạn:
- OptionParser.disable_interspersed_args()¶
Đặt phân tích cú pháp để dừng ở tùy chọn không đầu tiên. Ví dụ: nếu
-avà-bđều là các tùy chọn đơn giản không có đối số, thìoptparsethường chấp nhận cú pháp này:prog -a arg1 -b arg2
và coi nó tương đương với
prog -a -b arg1 arg2
Để tắt tính năng này, hãy gọi
disable_interspersed_args(). Điều này khôi phục cú pháp Unix truyền thống, trong đó việc phân tích cú pháp tùy chọn dừng lại với đối số không phải tùy chọn đầu tiên.Sử dụng tùy chọn này nếu bạn có bộ xử lý lệnh chạy một lệnh khác có các tùy chọn riêng và bạn muốn đảm bảo các tùy chọn này không bị nhầm lẫn. Ví dụ: mỗi lệnh có thể có một bộ tùy chọn khác nhau.
- OptionParser.enable_interspersed_args()¶
Đặt phân tích cú pháp để không dừng ở tùy chọn không đầu tiên, cho phép chuyển đổi xen kẽ với các đối số lệnh. Đây là hành vi mặc định.
- OptionParser.get_option(opt_str)¶
Trả về phiên bản Tùy chọn có chuỗi tùy chọn opt_str hoặc
Nonenếu không có tùy chọn nào có chuỗi tùy chọn đó.
- OptionParser.has_option(opt_str)¶
Trả về
Truenếu OptionParser có tùy chọn với chuỗi tùy chọn opt_str (ví dụ:-qhoặc--verbose).
- OptionParser.remove_option(opt_str)¶
Nếu
OptionParsercó tùy chọn tương ứng với opt_str thì tùy chọn đó sẽ bị loại bỏ. Nếu tùy chọn đó cung cấp bất kỳ chuỗi tùy chọn nào khác thì tất cả các chuỗi tùy chọn đó sẽ không hợp lệ. Nếu opt_str không xuất hiện trong bất kỳ tùy chọn nào thuộcOptionParsernày, hãy tăngValueError.
Xung đột giữa các lựa chọn¶
Nếu không cẩn thận, bạn rất dễ xác định các tùy chọn có chuỗi tùy chọn xung đột nhau:
Parser.add_option("-n", "--dry-run", ...)
...
Parser.add_option("-n", "--noisy", ...)
(Điều này đặc biệt đúng nếu bạn đã xác định lớp con OptionParser của riêng mình bằng một số tùy chọn tiêu chuẩn.)
Mỗi khi bạn thêm một tùy chọn, optparse sẽ kiểm tra xung đột với các tùy chọn hiện có. Nếu tìm thấy bất kỳ điều gì, nó sẽ gọi cơ chế xử lý xung đột hiện tại. Bạn có thể đặt cơ chế xử lý xung đột trong hàm tạo
trình phân tích cú pháp = OptionParser(..., xung đột_handler=handler)
hoặc với một cuộc gọi riêng:
trình phân tích cú pháp.set_conflict_handler(trình xử lý)
Các trình xử lý xung đột có sẵn là:
"error"(mặc định)giả sử xung đột tùy chọn là lỗi lập trình và tăng
OptionConflictError"resolve"giải quyết xung đột tùy chọn một cách thông minh (xem bên dưới)
Ví dụ: hãy xác định một OptionParser giải quyết xung đột một cách thông minh và thêm các tùy chọn xung đột vào nó:
trình phân tích cú pháp = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="không gây hại")
Parser.add_option("-n", "--noisy", ..., help="ồn ào")
Tại thời điểm này, optparse phát hiện ra rằng tùy chọn được thêm trước đó đã sử dụng chuỗi tùy chọn -n. Vì conflict_handler là "resolve" nên nó sẽ giải quyết tình huống này bằng cách xóa -n khỏi danh sách chuỗi tùy chọn của tùy chọn trước đó. Bây giờ --dry-run là cách duy nhất để người dùng kích hoạt tùy chọn đó. Nếu người dùng yêu cầu trợ giúp, thông báo trợ giúp sẽ phản ánh rằng:
Tùy chọn:
--chạy khô không gây hại gì
...
-n, --ồn ào ồn ào
Có thể cắt bớt các chuỗi tùy chọn cho một tùy chọn đã thêm trước đó cho đến khi không còn chuỗi tùy chọn nào và người dùng không có cách nào gọi tùy chọn đó từ dòng lệnh. Trong trường hợp đó, optparse loại bỏ hoàn toàn tùy chọn đó nên nó không hiển thị trong văn bản trợ giúp hoặc bất kỳ nơi nào khác. Tiếp tục với OptionParser hiện có của chúng tôi:
Parser.add_option("--dry-run", ..., help="tùy chọn chạy thử mới")
Tại thời điểm này, tùy chọn -n/--dry-run ban đầu không còn truy cập được nữa nên optparse sẽ xóa nó, để lại văn bản trợ giúp này:
Tùy chọn:
...
-n, --ồn ào ồn ào
--dry-run tùy chọn chạy khô mới
Dọn dẹp¶
Các phiên bản OptionParser có một số tham chiếu tuần hoàn. Đây không phải là vấn đề đối với trình thu gom rác của Python, nhưng bạn có thể muốn phá vỡ các tham chiếu tuần hoàn một cách rõ ràng bằng cách gọi destroy() trên OptionParser sau khi bạn đã hoàn tất. Điều này đặc biệt hữu ích trong các ứng dụng chạy dài, nơi có thể truy cập được các biểu đồ đối tượng lớn từ OptionParser của bạn.
Các phương pháp khác¶
OptionParser hỗ trợ một số phương thức công khai khác:
- OptionParser.set_usage(usage)¶
Đặt chuỗi sử dụng theo các quy tắc được mô tả ở trên cho đối số từ khóa hàm tạo
usage. TruyềnNonesẽ đặt chuỗi sử dụng mặc định; sử dụngoptparse.SUPPRESS_USAGEđể chặn thông báo sử dụng.
- OptionParser.print_usage(file=None)¶
In thông báo sử dụng cho chương trình hiện tại (
self.usage) thành file (thiết bị xuất chuẩn mặc định). Bất kỳ sự xuất hiện nào của chuỗi%progtrongself.usageđều được thay thế bằng tên của chương trình hiện tại. Không có gì nếuself.usagetrống hoặc không được xác định.
- OptionParser.get_usage()¶
Tương tự như
print_usage()nhưng trả về chuỗi sử dụng thay vì in ra.
- OptionParser.set_defaults(dest=value, ...)¶
Đặt giá trị mặc định cho một số đích tùy chọn cùng một lúc. Sử dụng
set_defaults()là cách ưu tiên để đặt giá trị mặc định cho các tùy chọn vì nhiều tùy chọn có thể chia sẻ cùng một đích. Ví dụ: nếu một số tùy chọn "chế độ" đều đặt cùng một đích đến thì bất kỳ tùy chọn nào trong số chúng đều có thể đặt mặc định và tùy chọn cuối cùng sẽ thắng:parser.add_option("--advanced", action="store_const", dest="mode", const="nâng cao", mặc định="người mới") # overridden bên dưới parser.add_option("--novice", action="store_const", dest="mode", const="người mới", cài đặt mặc định="nâng cao") # overrides ở trên
Để tránh sự nhầm lẫn này, hãy sử dụng
set_defaults():trình phân tích cú pháp.set_defaults(mode="advanced") parser.add_option("--advanced", action="store_const", dest="mode", const="nâng cao") parser.add_option("--novice", action="store_const", dest="mode", const="người mới")
Tùy chọn gọi lại¶
Khi các loại và hành động tích hợp sẵn của optparse không đủ đáp ứng nhu cầu của bạn, bạn có hai lựa chọn: mở rộng optparse hoặc xác định tùy chọn gọi lại. Việc mở rộng optparse mang tính tổng quát hơn nhưng lại quá mức cần thiết đối với nhiều trường hợp đơn giản. Thông thường, một cuộc gọi lại đơn giản là tất cả những gì bạn cần.
Có hai bước để xác định tùy chọn gọi lại:
tự xác định tùy chọn bằng hành động
"callback"viết cuộc gọi lại; đây là một hàm (hoặc phương thức) có ít nhất bốn đối số, như được mô tả bên dưới
Xác định tùy chọn gọi lại¶
Như mọi khi, cách dễ nhất để xác định tùy chọn gọi lại là sử dụng phương thức OptionParser.add_option(). Ngoài action, thuộc tính tùy chọn duy nhất bạn phải chỉ định là callback, hàm để gọi
parser.add_option("-c", action="callback", callback=my_callback)
callback là một hàm (hoặc đối tượng có thể gọi khác), vì vậy bạn phải xác định my_callback() khi tạo tùy chọn gọi lại này. Trong trường hợp đơn giản này, optparse thậm chí không biết liệu -c có nhận bất kỳ đối số nào hay không, điều này thường có nghĩa là tùy chọn này không có đối số---chỉ sự hiện diện của -c trên dòng lệnh là tất cả những gì nó cần biết. Tuy nhiên, trong một số trường hợp, bạn có thể muốn lệnh gọi lại của mình sử dụng số lượng đối số dòng lệnh tùy ý. Đây là lúc việc viết lệnh gọi lại trở nên khó khăn; nó sẽ được đề cập sau trong phần này.
optparse luôn chuyển bốn đối số cụ thể cho lệnh gọi lại của bạn và nó sẽ chỉ chuyển các đối số bổ sung nếu bạn chỉ định chúng thông qua callback_args và callback_kwargs. Do đó, chữ ký hàm gọi lại tối thiểu là:
def my_callback(tùy chọn, opt, value, trình phân tích cú pháp):
Bốn đối số cho lệnh gọi lại được mô tả bên dưới.
Có một số thuộc tính tùy chọn khác mà bạn có thể cung cấp khi xác định tùy chọn gọi lại:
typecó ý nghĩa thông thường: như với các hành động
"store"hoặc"append", nó hướng dẫnoptparsesử dụng một đối số và chuyển đổi nó thànhtype. Tuy nhiên, thay vì lưu trữ (các) giá trị đã chuyển đổi ở bất kỳ đâu,optparsechuyển nó tới hàm gọi lại của bạn.nargscũng có ý nghĩa thông thường: nếu nó được cung cấp và > 1,
optparsesẽ sử dụng các đối sốnargs, mỗi đối số đó phải có thể chuyển đổi thànhtype. Sau đó, nó chuyển một bộ giá trị đã chuyển đổi sang lệnh gọi lại của bạn.callback_argsmột bộ đối số vị trí bổ sung để chuyển đến lệnh gọi lại
callback_kwargsmột từ điển các đối số từ khóa bổ sung để chuyển đến cuộc gọi lại
Cách gọi lại¶
Tất cả các cuộc gọi lại được gọi như sau:
func(tùy chọn, opt_str, giá trị, trình phân tích cú pháp, *args, **kwargs)
ở đâu
optionlà phiên bản Tùy chọn đang gọi lại cuộc gọi lại
opt_strlà chuỗi tùy chọn nhìn thấy trên dòng lệnh đang kích hoạt lệnh gọi lại. (Nếu sử dụng tùy chọn dài viết tắt,
opt_strsẽ là chuỗi tùy chọn chuẩn, đầy đủ---ví dụ: nếu người dùng đặt--footrên dòng lệnh làm tên viết tắt cho--foobarthìopt_strsẽ là"--foobar".)valuelà đối số cho tùy chọn này được thấy trên dòng lệnh.
optparsesẽ chỉ mong đợi một đối số nếutypeđược đặt; loạivaluesẽ là loại được ngụ ý bởi loại tùy chọn. Nếutypecho tùy chọn này làNone(không có đối số dự kiến), thìvaluesẽ làNone. Nếunargs> 1,valuesẽ là một bộ giá trị thuộc loại thích hợp.parserlà phiên bản OptionParser điều khiển toàn bộ nội dung, chủ yếu hữu ích vì bạn có thể truy cập một số dữ liệu thú vị khác thông qua các thuộc tính phiên bản của nó:
parser.largsdanh sách hiện tại của các đối số còn sót lại, tức là. các đối số đã được sử dụng nhưng không phải là đối số tùy chọn cũng như đối số tùy chọn. Vui lòng sửa đổi
parser.largs, ví dụ: bằng cách thêm nhiều đối số vào nó. (Danh sách này sẽ trở thànhargs, giá trị trả về thứ hai củaparse_args().)parser.rargsdanh sách hiện tại của các đối số còn lại, tức là. với
opt_strvàvalue(nếu có) đã bị xóa và chỉ các đối số theo sau chúng vẫn còn đó. Vui lòng sửa đổiparser.rargs, ví dụ: bằng cách tiêu tốn nhiều đối số hơn.parser.valuesđối tượng nơi các giá trị tùy chọn được lưu trữ theo mặc định (một phiên bản của optparse.OptionValues). Điều này cho phép lệnh gọi lại sử dụng cơ chế tương tự như phần còn lại của
optparseđể lưu trữ các giá trị tùy chọn; bạn không cần phải loay hoay với toàn cầu hoặc đóng cửa. Bạn cũng có thể truy cập hoặc sửa đổi (các) giá trị của bất kỳ tùy chọn nào đã gặp trên dòng lệnh.
argslà một bộ đối số vị trí tùy ý được cung cấp thông qua thuộc tính tùy chọn
callback_args.kwargslà một từ điển gồm các đối số từ khóa tùy ý được cung cấp qua
callback_kwargs.
Phát sinh lỗi trong cuộc gọi lại¶
Hàm gọi lại sẽ tăng OptionValueError nếu có bất kỳ vấn đề nào với tùy chọn hoặc (các) đối số của nó. optparse phát hiện ra điều này và kết thúc chương trình, in thông báo lỗi mà bạn cung cấp cho stderr. Thông điệp của bạn phải rõ ràng, ngắn gọn, chính xác và đề cập đến phương án có lỗi. Nếu không, người dùng sẽ khó nhận ra mình đã làm gì sai.
Ví dụ gọi lại 1: gọi lại tầm thường¶
Dưới đây là ví dụ về tùy chọn gọi lại không có đối số và chỉ ghi lại rằng tùy chọn đã được nhìn thấy:
def record_foo_seen(tùy chọn, opt_str, giá trị, trình phân tích cú pháp):
trình phân tích cú pháp.values.saw_foo = Đúng
parser.add_option("--foo", action="callback", callback=record_foo_seen)
Tất nhiên, bạn có thể làm điều đó với hành động "store_true".
Ví dụ gọi lại 2: kiểm tra thứ tự tùy chọn¶
Đây là một ví dụ thú vị hơn một chút: ghi lại thực tế là -a được nhìn thấy, nhưng sẽ bùng nổ nếu nó xuất hiện sau -b trong dòng lệnh.
def check_order(tùy chọn, opt_str, giá trị, trình phân tích cú pháp):
nếu trình phân tích cú pháp.values.b:
raise OptionValueError("không thể sử dụng -a sau -b")
trình phân tích cú pháp.values.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")
Ví dụ gọi lại 3: kiểm tra thứ tự tùy chọn (tổng quát)¶
Nếu bạn muốn sử dụng lại lệnh gọi lại này cho một số tùy chọn tương tự (đặt cờ, nhưng sẽ nổ tung nếu -b đã được nhìn thấy), nó cần một chút công việc: thông báo lỗi và cờ mà nó đặt phải được khái quát hóa.
def check_order(tùy chọn, opt_str, giá trị, trình phân tích cú pháp):
nếu trình phân tích cú pháp.values.b:
raise OptionValueError("không thể sử dụng %s sau -b" % opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')
Ví dụ gọi lại 4: kiểm tra điều kiện tùy ý¶
Tất nhiên, bạn có thể đặt bất kỳ điều kiện nào vào đó---bạn không bị giới hạn trong việc kiểm tra giá trị của các tùy chọn đã được xác định. Ví dụ: nếu bạn có các tùy chọn không nên gọi khi trăng tròn, tất cả những gì bạn phải làm là thế này:
def check_moon (tùy chọn, opt_str, giá trị, trình phân tích cú pháp):
nếu is_moon_full():
raise OptionValueError("tùy chọn %s không hợp lệ khi trăng tròn"
% opt_str)
setattr(parser.values, option.dest, 1)
...
trình phân tích cú pháp.add_option("--foo",
action="callback", callback=check_moon, dest="foo")
(Định nghĩa về is_moon_full() được để lại như một bài tập cho người đọc.)
Ví dụ gọi lại 5: đối số cố định¶
Mọi thứ trở nên thú vị hơn một chút khi bạn xác định các tùy chọn gọi lại có số lượng đối số cố định. Việc chỉ định rằng tùy chọn gọi lại nhận các đối số cũng tương tự như việc xác định tùy chọn "store" hoặc "append": nếu bạn xác định type thì tùy chọn này sẽ nhận một đối số phải có thể chuyển đổi sang loại đó; nếu bạn xác định thêm nargs thì tùy chọn này sẽ lấy các đối số nargs.
Đây là một ví dụ chỉ mô phỏng hành động "store" tiêu chuẩn:
def store_value (tùy chọn, opt_str, giá trị, trình phân tích cú pháp):
setattr(parser.values, option.dest, value)
...
trình phân tích cú pháp.add_option("--foo",
hành động="gọi lại", gọi lại=store_value,
type="int", nargs=3, dest="foo")
Lưu ý rằng optparse đảm nhiệm việc sử dụng 3 đối số và chuyển đổi chúng thành số nguyên cho bạn; tất cả những gì bạn phải làm là lưu trữ chúng. (Hoặc bất cứ điều gì; rõ ràng là bạn không cần gọi lại cho ví dụ này.)
Ví dụ gọi lại 6: đối số biến¶
Mọi thứ trở nên rắc rối khi bạn muốn có một tùy chọn để nhận số lượng đối số thay đổi. Trong trường hợp này, bạn phải viết một lệnh gọi lại vì optparse không cung cấp bất kỳ khả năng tích hợp nào cho nó. Và bạn phải giải quyết một số vấn đề phức tạp nhất định của việc phân tích cú pháp dòng lệnh Unix thông thường mà optparse thường xử lý cho bạn. Cụ thể, các lệnh gọi lại phải triển khai các quy tắc thông thường cho các đối số -- và - trần:
--hoặc-có thể là đối số tùy chọn--trần (nếu không phải là đối số cho một số tùy chọn): tạm dừng xử lý dòng lệnh và loại bỏ---trần (nếu không phải là đối số cho một số tùy chọn): tạm dừng xử lý dòng lệnh nhưng giữ lại-(thêm nó vàoparser.largs)
Nếu bạn muốn một tùy chọn có số lượng đối số thay đổi thì có một số vấn đề tế nhị, phức tạp cần phải lo lắng. Cách triển khai chính xác mà bạn chọn sẽ dựa trên những đánh đổi mà bạn sẵn sàng thực hiện cho ứng dụng của mình (đó là lý do tại sao optparse không hỗ trợ trực tiếp loại điều này).
Tuy nhiên, đây là một thử thách trong cuộc gọi lại cho một tùy chọn có các đối số thay đổi
def vararg_callback(tùy chọn, opt_str, giá trị, trình phân tích cú pháp):
khẳng định giá trị là Không có
giá trị = []
def có thể nổi (str):
thử:
phao(str)
trả về Đúng
ngoại trừ ValueError:
trả về Sai
cho arg trong trình phân tích cú pháp.rargs:
# stop trên --foo tùy chọn thích
nếu arg[:2] == "--" và len(arg) > 2:
phá vỡ
# stop trên -a, nhưng không phải trên -3 hoặc -3.0
nếu arg[:1] == "-" và len(arg) > 1 và không thể nổi (arg):
phá vỡ
value.append(arg)
del parser.rargs[:len(value)]
setattr(parser.values, option.dest, value)
...
parser.add_option("-c", "--callback", dest="vararg_attr",
hành động="gọi lại", gọi lại=vararg_callback)
Mở rộng optparse¶
Vì hai yếu tố kiểm soát chính trong cách optparse diễn giải các tùy chọn dòng lệnh là hành động và loại của từng tùy chọn, nên hướng mở rộng có khả năng nhất là thêm các hành động mới và loại mới.
Thêm loại mới¶
Để thêm các loại mới, bạn cần xác định lớp con của lớp Option của optparse. Lớp này có một số thuộc tính xác định các loại của optparse: TYPES và TYPE_CHECKER.
- Option.TYPES¶
Một bộ tên loại; trong lớp con của bạn, chỉ cần xác định một bộ
TYPESmới được xây dựng trên bộ tiêu chuẩn.
- Option.TYPE_CHECKER¶
Một từ điển ánh xạ tên loại tới các chức năng kiểm tra loại. Hàm kiểm tra loại có chữ ký sau
def check_mytype(tùy chọn, opt, value)
trong đó
optionlà một phiên bảnOption,optlà một chuỗi tùy chọn (ví dụ:-f) vàvaluelà chuỗi từ dòng lệnh phải được kiểm tra và chuyển đổi thành loại bạn muốn.check_mytype()sẽ trả về một đối tượng thuộc loại giả địnhmytype. Giá trị được hàm kiểm tra loại trả về sẽ xuất hiện trong phiên bản OptionValues đượcOptionParser.parse_args()trả về hoặc được chuyển đến lệnh gọi lại dưới dạng tham sốvalue.Chức năng kiểm tra loại của bạn sẽ tăng
OptionValueErrornếu gặp bất kỳ vấn đề nào.OptionValueErrorlấy một đối số chuỗi đơn, được truyền nguyên trạng cho phương thứcerror()củaOptionParser, lần lượt thêm tên chương trình và chuỗi"error:"và in mọi thứ vào stderr trước khi kết thúc quá trình.
Đây là một ví dụ ngớ ngẩn minh họa việc thêm loại tùy chọn "complex" để phân tích các số phức kiểu Python trên dòng lệnh. (Điều này thậm chí còn ngớ ngẩn hơn trước đây vì optparse 1.3 đã thêm hỗ trợ tích hợp cho các số phức, nhưng đừng bận tâm.)
Đầu tiên, nhập khẩu cần thiết:
từ bản sao nhập bản sao
từ tùy chọn nhập optparse, OptionValueError
Trước tiên, bạn cần xác định trình kiểm tra loại của mình vì nó được đề cập đến sau (trong thuộc tính lớp TYPE_CHECKER của lớp con Tùy chọn của bạn):
def check_complex(tùy chọn, opt, value):
thử:
trả về phức tạp (giá trị)
ngoại trừ ValueError:
nâng cao OptionValueError(
"tùy chọn %s: giá trị phức hợp không hợp lệ: %r" % (tùy chọn, giá trị))
Cuối cùng, lớp con Tùy chọn:
lớp MyOption (Tùy chọn):
TYPES = Option.TYPES + ("phức tạp",)
TYPE_CHECKER = sao chép(Option.TYPE_CHECKER)
TYPE_CHECKER["complex"] = check_complex
(Nếu chúng tôi không tạo copy() của Option.TYPE_CHECKER, thì cuối cùng chúng tôi sẽ sửa đổi thuộc tính TYPE_CHECKER của lớp Tùy chọn của optparse. Đây là Python, không có gì ngăn cản bạn làm điều đó ngoại trừ cách cư xử tốt và lẽ thường.)
Thế thôi! Bây giờ bạn có thể viết một tập lệnh sử dụng loại tùy chọn mới giống như bất kỳ tập lệnh dựa trên optparse- nào khác, ngoại trừ bạn phải hướng dẫn OptionParser sử dụng MyOption thay vì Option:
trình phân tích cú pháp = OptionParser(option_class=MyOption)
Parser.add_option("-c", type="complex")
Ngoài ra, bạn có thể xây dựng danh sách tùy chọn của riêng mình và chuyển nó tới OptionParser; nếu bạn không sử dụng add_option() theo cách trên, bạn không cần phải cho OptionParser biết nên sử dụng lớp tùy chọn nào:
option_list = [MyOption("-c", action="store", type="complex", dest="c")]
trình phân tích cú pháp = OptionParser(option_list=option_list)
Thêm hành động mới¶
Việc thêm hành động mới phức tạp hơn một chút vì bạn phải hiểu rằng optparse có một số cách phân loại cho hành động:
- hành động "lưu trữ"
các hành động dẫn đến việc
optparselưu trữ một giá trị vào một thuộc tính của phiên bản OptionValues hiện tại; các tùy chọn này yêu cầu cung cấp thuộc tínhdestcho hàm tạo Tùy chọn.- hành động "gõ"
các hành động lấy một giá trị từ dòng lệnh và mong đợi nó thuộc một loại nhất định; hay đúng hơn là một chuỗi có thể được chuyển đổi thành một loại nhất định. Các tùy chọn này yêu cầu thuộc tính
typecho hàm tạo Tùy chọn.
Đây là các tập hợp chồng chéo: một số hành động "lưu trữ" mặc định là "store", "store_const", "append" và "count", trong khi các hành động "đã nhập" mặc định là "store", "append" và "callback".
Khi thêm một hành động, bạn cần phân loại nó bằng cách liệt kê nó vào ít nhất một trong các thuộc tính lớp sau của Tùy chọn (tất cả đều là danh sách các chuỗi):
- Option.ACTIONS¶
Tất cả các hành động phải được liệt kê trong ACTIONS.
- Option.STORE_ACTIONS¶
hành động "lưu trữ" cũng được liệt kê ở đây.
- Option.TYPED_ACTIONS¶
hành động "đã gõ" cũng được liệt kê ở đây.
- Option.ALWAYS_TYPED_ACTIONS¶
Các hành động luôn có một loại (tức là các tùy chọn của chúng luôn nhận một giá trị) cũng được liệt kê thêm ở đây. Tác dụng duy nhất của việc này là
optparsechỉ định loại mặc định,"string", cho các tùy chọn không có loại rõ ràng có hành động được liệt kê trongALWAYS_TYPED_ACTIONS.
Để thực sự triển khai hành động mới của mình, bạn phải ghi đè phương thức take_action() của Tùy chọn và thêm trường hợp nhận dạng hành động của bạn.
Ví dụ: hãy thêm một hành động "extend". Điều này tương tự như hành động "append" tiêu chuẩn, nhưng thay vì lấy một giá trị từ dòng lệnh và thêm nó vào danh sách hiện có, "extend" sẽ lấy nhiều giá trị trong một chuỗi được phân cách bằng dấu phẩy và mở rộng danh sách hiện có với chúng. Tức là, nếu --names là một tùy chọn "extend" thuộc loại "string", thì dòng lệnh
--names=foo,bar --names blah --names ding,dong
sẽ dẫn đến một danh sách
["foo", "bar", "blah", "ding", "dong"]
Một lần nữa chúng ta định nghĩa một lớp con của Option:
lớp MyOption(Tùy chọn):
ACTIONS = Option.ACTIONS + ("mở rộng",)
STORE_ACTIONS = Option.STORE_ACTIONS + ("mở rộng",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("mở rộng",)
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("mở rộng",)
def take_action(self, action, dest, opt, value, value, trình phân tích cú pháp):
nếu hành động == "mở rộng":
lvalue = value.split(",")
value.ensure_value(dest, []).extend(lvalue)
khác:
Tùy chọn.take_action(
tự, hành động, đích, opt, giá trị, giá trị, trình phân tích cú pháp)
Đặc điểm lưu ý:
"extend"đều mong đợi một giá trị trên dòng lệnh và lưu trữ giá trị đó ở đâu đó, do đó, nó có trong cảSTORE_ACTIONSvàTYPED_ACTIONS.để đảm bảo rằng
optparsechỉ định loại hành động"string"mặc định cho"extend", chúng tôi cũng đặt hành động"extend"trongALWAYS_TYPED_ACTIONS.MyOption.take_action()chỉ thực hiện một hành động mới này và chuyển quyền kiểm soát trở lạiOption.take_action()cho các hành độngoptparsetiêu chuẩn.valueslà một phiên bản của lớp optparse_parser.Values, lớp này cung cấp phương thứcensure_value()rất hữu ích.ensure_value()thực chất làgetattr()có van an toàn; nó được gọi làvalue.ensure_value(attr, value)
Nếu thuộc tính
attrcủavalueskhông tồn tại hoặc làNone, thì trước tiên, Ensure_value() sẽ đặt thuộc tính đó thànhvalue, sau đó trả vềvalue. Điều này rất thuận tiện cho các hành động như"extend","append"và"count", tất cả đều tích lũy dữ liệu trong một biến và dự kiến biến đó thuộc một loại nhất định (danh sách cho hai biến đầu tiên, một số nguyên cho biến sau). Việc sử dụngensure_value()có nghĩa là các tập lệnh sử dụng hành động của bạn không phải lo lắng về việc đặt giá trị mặc định cho đích tùy chọn được đề cập; họ chỉ có thể để mặc định vìNonevàensure_value()sẽ đảm nhiệm việc thực hiện đúng khi cần.
Ngoại lệ¶
- exception optparse.OptionError¶
Xảy ra nếu một phiên bản
Optionđược tạo với các đối số không hợp lệ hoặc không nhất quán.
- exception optparse.OptionConflictError¶
Tăng lên nếu các tùy chọn xung đột được thêm vào
OptionParser.
- exception optparse.OptionValueError¶
Tăng lên nếu gặp giá trị tùy chọn không hợp lệ trên dòng lệnh.
- exception optparse.BadOptionError¶
Tăng lên nếu một tùy chọn không hợp lệ được truyền vào dòng lệnh.
- exception optparse.AmbiguousOptionError¶
Xảy ra nếu một tùy chọn không rõ ràng được truyền trên dòng lệnh.