[英]argparse: building a list of dict from CLI arguments?
設計分層 CLI 程序。 就像是:
$ python -m foo -'{' -c 'wow' -b 'has' -d 55 -'}' \
-'{' -c 'haz' -b 'wow' -'}' \
-'{' -d 56 -'}'
我想return
:
[
{ 'c': 'wow', 'b': 'has', 'd': 55 },
{ 'c': 'haz', 'b': 'wow' },
{ 'd': 56 }
]
主要問題:我如何在argparse
構建它,即沒有在vars(parser.parse_args())
之后運行的單獨函數?
輔助問題:是否在 CLI 界面中構建這樣的層次結構 - 即,不是在外部 json 文件中或作為type=yaml.loads
- 但作為違反某些約定的正確 CLI 屬性/值,這應該讓我重新考慮這種設計嗎?
PS:我可以使用sys.argv
、一個額外的list
和一個范圍標量在沒有 argparse 的情況下輕松創建它。 但是argparse
會給我自動幫助、自動完成、默認值、類型安全等等……所以我更願意使用它。
編輯: sys.argv[1:]
示例:
[ '-m', 'foo', '-{', '-c', 'wow', '-b', 'has', '-d', '55', '-}',
'-{', '-c', 'haz', '-b', 'wow', '-}', '-{', '-d', '56', '-}' ]
我認為有一種松散的“約定”,即 CLI 參數應該相當簡單; 一旦您開始在命令行上放置大量數據,那么也許您應該重新考慮您的設計。 畢竟,文件旨在保存數據。
構建了一個基本版本,只處理一級層次結構:
from argparse import ArgumentParser, ArgumentTypeError
from sys import argv
from pprint import pprint
def build_parser():
parser = ArgumentParser(prog='python -m foo', description='.')
parser.add_argument('-c')
parser.add_argument('-b')
parser.add_argument('-d', type=int)
return parser
def main():
level, working, whole = 0, [], []
for arg in argv[1:]:
if arg == '-{':
level += 1
elif arg == '-}':
whole.append(tuple(working))
working.clear()
level -= 1
else:
working.append(arg)
if level & 1 != 0:
raise ArgumentTypeError('Imbalanced {}')
parser = build_parser()
return tuple(map(lambda args: parser.parse_args(args), whole))
# For list of dicts, modify ^ vars(parser.parse_args(args))
if __name__ == '__main__':
pprint(main(), indent=4)
$ python -m foo -'{' -c 'wow' -b 'has' -d 55 -'}' \
-'{' -c 'haz' -b 'wow' -'}' \
-'{' -d 56 -'}'
( Namespace(b='has', c='wow', d=55),
Namespace(b='wow', c='haz', d=None),
Namespace(b=None, c=None, d=56))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.