我有一個帶有一些子決議器的決議器。我設定了一個用于所有子決議器的全域引數。這是相關的片段
parser = argparse.ArgumentParser(prog="my_prog", add_help=False)
parser.add_argument('-d', '--debug', action='store_true', help='debug flag')
subparsers = parser.add_subparsers(dest="subparser_name", help='some help notes')
parser_cmd1 = subparsers.add_parser('cmd1', parents=[parser])
parser_cmd1.add_argument('-f', '-foo', type=str, action=foo, required=False, help='foo command')
parser_cmd2 = subparsers.add_parser('cmd2', parents=[parser])
parser_cmd2.add_argument('-b', '-bar', type=str, action=bar, required=False, help='bar command')
args = parser.parse_args()
parser = args.subparser_name
print(args)
if args.debug:
logging.basicConfig(level=logging.INFO)
if parser == 'cmd1':
if args.foo:
//do foo stuff
if parser == 'cmd2':
if args.bar:
//do bar stuff
所以你可以像這樣的命令my_prog.py cmd1 -d -f inp_str。這是問題所在:subparser_name 為 None。print(args) 的輸出看起來像這樣
Namespace(debug=True, foo="inp_str", subparser_name=None)
在我添加全域除錯引數之前,subparser_name 將是我運行的命令的名稱,即“cmd1”或“cmd2”。現在,它是“無”。即使在子決議器創建中添加了 parents=[parser]。我怎樣才能解決這個問題?我怎么知道呼叫了哪個命令?
uj5u.com熱心網友回復:
將公共 args 拆分為單獨的 ArgumentParser,然后將其用作子決議器的父級。此外,您的 foo 和 bar 選項是使用 -foo 和 -bar 指定的,whi 應該是 --foo 和 --bar。此外,您沒有這些的默認值,例如當 -f/--foo 未正確指定時 args.foo 不存在。
這效果更好:
import argparse
common_args = argparse.ArgumentParser(prog="my_prog", add_help=False)
common_args.add_argument('-d', '--debug', action='store_true', help='debug flag')
parser = argparse.ArgumentParser(prog="my_prog", add_help=True)
subparsers = parser.add_subparsers(dest="subparser_name", help='some help notes')
parser_cmd1 = subparsers.add_parser('cmd1', parents=[common_args])
parser_cmd1.add_argument('-f', '--foo', type=str, default='', required=False, help='foo command')
parser_cmd2 = subparsers.add_parser('cmd2', parents=[common_args])
parser_cmd2.add_argument('-b', '--bar', type=str, default='', required=False, help='bar command')
args = parser.parse_args()
parser = args.subparser_name
print(args)
if args.debug:
logging.basicConfig(level=logging.INFO)
if parser == 'cmd1':
if args.foo:
#//do foo stuff
print( f"foo {args.foo}" )
if parser == 'cmd2':
if args.bar:
#//do bar stuff
print( f"bar {args.bar}" )
運行:
args.py cmd1 -f asd
輸出:
Namespace(subparser_name='cmd1', debug=False, foo='asd')
foo asd
更新:
如果您希望能夠使用 eg args.py -d cmd1then 在創建 時parser指定parents=[common_args]
parser = argparse.ArgumentParser(prog="my_prog", add_help=True, parents=[common_args])
下次您提出問題時,請確保您僅將代碼作為最小的可重現示例發布 - 即可以在不添加任何內容的情況下運行
uj5u.com熱心網友回復:
子決議器的默認值優先于主決議器設定的任何值 - 默認值或用戶輸入。主要set the subparser_name對 'cmd1' 執行,但子決議器將其更改回默認的None.
雖然在您的測驗用例中并不明顯,但debug在兩個級別進行定義都存在相同的問題。子決議器的默認值會覆寫 main 中設定的任何內容。
通常,dest在主決議器和子決議器中使用相同的內容并不是一個好主意。標志可以相同,但dest應該不同 - 至少如果您想查看 main 設定的任何內容。
使用主決議器作為parent子決議器,只是在尋求混淆。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/364369.html
