2013-05-28 20 views
12

Chương trình của tôi nên bao gồm các tùy chọn sau, phân tích đúng bằng argparse:Python 2.7 argparse: Làm thế nào để lồng các đối số độc quyền tùy chọn khác nhau đúng cách?

  1. hoàn toàn không bắt buộc: [-h, --help][-v, --version]
  2. loại trừ lẫn nhau: [-f FILE, --file FILE][-u URL, --url URL]
  3. tùy chọn nếu --url được chọn: [-V, --verbose]
  4. cần nếu hoặc là --file hoặc --url đã được chọn: [-F, --format FORMAT]

Các mô hình sử dụng mong muốn sẽ là:

prog.py [-h] [-v] [-f FILE (-F FORMAT) | -u URL [-V] (-F FORMAT) ] 

với yêu cầu -F áp dụng cho cả hai thành viên của nhóm loại trừ lẫn nhau.
Không chắc chắn rằng đó có phải là positional hay không.

Vì vậy, chúng ta có thể để chạy:

prog.py -u "http://foo.bar" -V -F csv 

và phân tích cú pháp la hét trong trường hợp tôi quên -F (như ông là nghĩa vụ phải).

Những gì tôi đã làm như vậy cho đến nay:

parser = ArgumentParser(decription='foo') 

group = parser.add_mutually_exclusive_group()  
group.add_argument('-f','--file', nargs=1, type=str, help='') 
group.add_argument('-u','--url', nargs=1, type=str, help='')  

parser.add_argument('-V','--verbose', action='store_true', default=False, help='') 
parser.add_argument('-F','--format', nargs=1, type=str, help='') 

Kể từ khi nó có một 'chế độ vani' để chạy mà không cần đối số dòng lệnh, tất cả các đối số phải là bắt buộc.

Làm cách nào tôi có thể triển khai điểm 3. và 4. vào mã của mình?

EDIT:
tôi đã cố gắng -f-u như subparsers, như mô tả here, nhưng lệnh con dường như bị đối xử như positionals và phân tích cú pháp mang lại cho tôi một error: too few arguments nếu tôi chạy nó không có đối số.

+2

bạn đã xem [docopt] (http://docopt.org/) chưa? Điểm bất lợi là nó cho phép các giá trị tùy chọn bắt đầu bằng '-' [ví dụ,' "-fa -F -u" '(định dạng là" -u "ở đây)] (https://gist.github.com/zed/b94e3e9945debe25826d) – jfs

+0

Là một trong các '-f' và' -u' được yêu cầu? Nếu vậy, tôi đang hình dung một giải pháp liên quan đến các tiểu ban hoặc các đối số vị trí. – chepner

+1

@chepner: không, chúng không có. tôi muốn chương trình cũng chạy mà không có args và tùy chọn, do đó, nó sẽ bắt đầu một hộp thoại người dùng hoặc thậm chí một GUI – ferkulat

Trả lời

5

Sử dụng nargs = 2 và tuple metavar xấp xỉ mục tiêu

parser = argparse.ArgumentParser(prog='PROG') 
group = parser.add_mutually_exclusive_group() 
group.add_argument('-f','--file', nargs=2, metavar=('FILE','FORMAT')) 
group.add_argument('-u','--url', nargs=2, metavar=('URL','FORMAT')) 
parser.add_argument('-V','--verbose', action='store_true',help='optional with url') 

của bạn trong đó sản xuất:

usage: PROG [-h] [-f FILE FORMAT | -u URL FORMAT] [-V] 

optional arguments: 
    -h, --help   show this help message and exit 
    -f FILE FORMAT, --file FILE FORMAT 
    -u URL FORMAT, --url URL FORMAT 
    -V, --verbose   optional with url 

Điều này đòi hỏi các định dạng cùng với tên tệp hoặc url, nó chỉ không yêu cầu -F. Vì những người khác đã ghi chú -V có thể bị bỏ qua trong trường hợp -f.


I tried -f and -u as subparsers, as described here, but subcommands seem to be treated like positionals and the parser gives me an error: too few arguments if i run it without arguments.

Trong phiên bản mới nhất (s) lệnh con không còn được coi là positionals yêu cầu. Đây là, tốt nhất tôi có thể nói, một tác dụng phụ của việc thay đổi thông báo lỗi là nhiều thông tin hơn. Thay vì _parse_known_args làm một:

if positionals: 
     self.error(_('too few arguments')) 

nó quét _actions để xem cái nào được yêu cầu, và sau đó liệt kê chúng theo tên trong thông báo lỗi. Điều này được thảo luận trong http://bugs.python.org/issue9253. Tôi biết sự thay đổi này đang được phát triển (3.4), và cũng có thể là 3.3.


2

Các điểm này có thể được thực thi trong optparse bằng cách sử dụng phương thức callback khi có một tùy chọn nhất định.

Tuy nhiên, trong argparse những tính năng này không có sẵn.

Bạn có thể thêm subparser cho số url và tùy chọn phụ file và phân tích cú pháp các seperatly này. từ sự giúp đỡ:

Note that the object returned by parse_args() will only contain attributes for the main parser and the subparser that was selected by the command line (and not any other subparsers). So in the example above, when the a command is specified, only the foo and bar attributes are present, and when the b command is specified, only the foo and baz attributes are present.

Nhưng tôi sẽ chỉ ghi lại đúng việc sử dụng, và chỉ cần bỏ qua các đối số mà không phải là áp dụng.

ví dụ:hãy để những hai dòng lệnh cư xử giống hệt nhau:

prog.py -f FILE -V 
prog.py -f FILE 
+1

' argparse 'đã tích hợp sẵn hỗ trợ cho các tùy chọn với một số biến đối số, cũng như các hành động tùy chỉnh để xử lý (các) đối số của một tùy chọn đã cho. Tuy nhiên, tôi đồng ý rằng trong trường hợp này, đơn giản nhất là chỉ cho phép '-V' và bỏ qua nó nếu' -f' được sử dụng. – chepner

+0

'optparse' không được dùng nữa và' argparse' là sự thay thế của nó. Xem: https://docs.python.org/3/library/argparse.html#upgrading-optparse-code –

Các vấn đề liên quan