(這是一個簡化的問題。)我正在編寫一個涉及Python組件的API。這些可能是功能,但具體來說,讓我們說他們是對象。我希望能夠從命令行解析各種組件的選項。使用Python/argparse創建可組合/分層命令行分析器
from argparse import ArgumentParser
class Foo(object):
def __init__(self, foo_options):
"""do stuff with options"""
"""..."""
class Bar(object):
def __init__(sef, bar_options):
"""..."""
def foo_parser():
"""(could also be a Foo method)"""
p = ArgumentParser()
p.add_argument('--option1')
#...
return p
def bar_parser(): "..."
但現在我希望能夠建立更大的組件:
def larger_component(options):
f1 = Foo(options.foo1)
f2 = Foo(options.foo2)
b = Bar(options.bar)
# ... do stuff with these pieces
精細。但是如何編寫適當的解析器?我們不妨這樣的事情:
def larger_parser(): # probably need to take some prefix/ns arguments
# general options to be overridden by p1, p2
# (this could be done automagically or by hand in `larger_component`):
p = foo_parser(prefix=None, namespace='foo')
p1 = foo_parser(prefix='first-foo-', namespace='foo1')
p2 = foo_parser(prefix='second-foo-', namespace='foo2')
b = bar_parser()
# (you wouldn't actually specify the prefix/namespace twice:)
return combine_parsers([(p1, namespace='foo1', prefix='first-foo-'),
(p2,...),p,b])
larger_component(larger_parser().parse_args())
# CLI should accept --foo1-option1, --foo2-option1, --option1 (*)
這看起來有點像的parents
功能,如果你忘了我們想要的前綴(以便能夠添加相同類型的多個解析器) 和可能命名空間(以便我們可以構建樹形結構的命名空間以反映組件的結構)。
當然,我們希望large_component和larger_parser以相同的方式組合,並且傳遞給某個組件的名稱空間對象應始終具有相同的內部形狀/命名結構。
麻煩似乎是在API基本上是關於變異的你分析器,但查詢它們是比較困難的 - 如果你直接打開一個 數據類型爲解析器,你可以只走這些對象。如果用戶編寫了一堆函數以手動添加參數給解析器,但是每個add_argument
調用都必須帶一個前綴,並且整個事情變得非常難以理解,並且可能不可組合,所以我設法破解了某些有些作用。 (你可以通過複製內部數據結構的某些部分來對此進行抽象...)。我也試圖子類parser
和group
對象...
你可以想象這可能使用更多的代數CLI-解析API是可能的,但我不認爲重寫這裏是一個很好的解決方案。
有沒有一種已知的/直接的方法來做到這一點?
你能證明你想使用一個命令行的一個例子?起初,它看起來像你想'subparsers'(這是argparse默認提供的),但我不能100%確定它是否適合你的需求。 – mgilson
'subparsers'似乎是關於解析器(解析器A,或B或...)的「總和」,而我想要一個「產品」(所有選項可同時使用)。 – Fixnum
有關示例,請參閱問題中用'(*)'指示的行。 – Fixnum