簡體   English   中英

你如何讓 argparse 選擇一個默認的子解析器?

[英]How do you get argparse to choose a default subparser?

我在script.py有以下代碼:

import argparse

parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='command')
sp.default = 'a'

a_parser = sp.add_parser('a')
b_parser = sp.add_parser('b')

a_parser.add_argument('--thing', default='thing')
b_parser.add_argument('--nothing', default='nothing')

args = parser.parse_args()
print(args)

我可以稱之為三種不同的方式:

$ python3 script.py
Namespace(command='a')
$ python3 script.py a
Namespace(command='a', thing='thing')
$ python3 script.py b
Namespace(command='b', nothing='nothing')

這只有一個問題:我想要的是,如果我在命令行上提供零個參數,則a_parser將成為結束解析和執行操作的那個。 顯然不是, sp.default只是設置command='a' ,不是我所期望的,也就是說,“哦,是的,用戶沒有在命令行上提供任何參數,但我知道這應該由a_parser處理。這里是Namespace(command='a', thing='thing') !”

有沒有一種方法,我可以argparse做到這一點? 我已經尋找了一些不同的選擇,但它們似乎都沒有真正提供我所追求的。 我想我可以通過制作 3 個不同的 ArgumentParsers 然后將參數傳遞給每個人來做一些麻煩事,盡管這聽起來有點惡心。

還有更好的選擇嗎?

首先是一個歷史記錄 - 子解析器不是可選的,它們仍然不在 Python2 中。 它們在 Py3 中是可選的這一事實是幾年前引入的一個錯誤。 所需參數的測試發生了變化,並且子解析器(一種位置)陷入了困境。 如果做得對,您應該必須明確地將子解析器設置為不需要。

子解析器的行為不像其他非必需參數,即帶有nargs='?' 或標記為沒有required參數。

在任何情況下,您的sp.default定義了將放入command dest 中的值,但它不會觸發a_parser的使用。 command='a'永遠不會被“評估”。

采用parse_known_args可能允許您與貶值剩余的字符串a_parser

沒有任何參數,我們可以這樣做:

In [159]: args, extras = parser.parse_known_args([])
In [160]: args
Out[160]: Namespace(command='a')
In [161]: extras
Out[161]: []

然后有條件地運行a_parser (如果命令是 'a' 但沒有 'thing')

In [163]: a_parser.parse_args(extras,namespace=args)
Out[163]: Namespace(command='a', thing='thing')

但是,如果我嘗試包含一個--thing值:

In [164]: args, extras = parser.parse_known_args('--thing ouch'.split())
usage: ipython3 [-h] {a,b} ...
ipython3: error: argument command: invalid choice: 'ouch' (choose from 'a', 'b')

它嘗試將“ouch”解析為子解析器名稱。 主解析器對--thing參數--thing

正如我在今天的另一個argparse問題中所解釋的那樣,頂級解析器會解析輸入,直到找到適合“子解析器”命令的內容(或者在本示例中引發錯誤)。 然后它將解析傳遞給子解析器。 之后它不會恢復解析。

在子解析器 args 之后添加頂級 argparse 參數

如何在 Python 2.7 中使用 Argparse 模塊設置默認子解析器

我對這個 Py2 請求的回答可能對你有用。 我第一次運行parse_known_args與不具有subparsers的分析器,並有條件地運行第二解析器處理該subparsers。

In [165]: firstp = argparse.ArgumentParser()
In [166]: args, extras = firstp.parse_known_args('--thing ouch'.split())
In [167]: args
Out[167]: Namespace()

如果extras沒有 'a' 或 'b' 調用a_parser (或者直接查看sys.argv[1:] ):

In [168]: extras
Out[168]: ['--thing', 'ouch']
In [169]: a_parser.parse_args(extras)
Out[169]: Namespace(thing='ouch')

或者修改extras以包含缺少的 subparser 命令:

In [170]: extras = ['a']+extras
In [171]: parser.parse_args(extras)
Out[171]: Namespace(command='a', thing='ouch')

在任何情況下, optional解析器在argparse都沒有很好地開發。 這是前一段時間所做更改的副作用,而不是經過深思熟慮的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM