2016-11-21 91 views
3

我正在使用argparse並且我有各種各樣的具有自己選項的組。在argparse中自定義組間幫助

現在與- 幫助選項我不想顯示默認情況下的所有選項。 --help僅顯示一組組選項。

其他組選項應該基於其它幫助選項顯示,爲--help_1--help_2

例如:

--help' to show Group 2 and 3 
--help_1' to show Group 11 and 12 
--help_2' to show Group 22 and 23 

我知道,我們可以使用禁用默認--help選項add_help = False但我如何才能顯示只選擇特定組的幫助。

我們可以從使用_action_groups屬性解析器組的列表,但他們沒有公開任何print_help()的選擇,因爲這樣的。

我的示例代碼:

parser = argparse.ArgumentParser(add_help=False) 

parser.add_argument('--help_a', action='store_true') 
parser.add_argument('--help_b', action='store_true') 

group1 = parser.add_argument_group("Feature 1") 
group1.add_argument('--foo1') 
group2 = parser.add_argument_group("Feature 2") 
group2.add_argument('--foo2') 
group3 = parser.add_argument_group("Feature 3") 
group3.add_argument('--foo3') 

# TODO: --help_a to only print "Feature 1" groups help 
# and --help_b to print Feature 2 and 3's help. 

編輯:使用subparser並加入解析器(而不是組)將解決上述。但subparser不適合我的情況,因爲我總是解析它,我只需要定製幫助來顯示。

+0

爲什麼不通過'less'? 'python command.py --help |少' –

+0

這在我看來並不正確。我不希望外部用戶使用我的API或腳本來解析他們。腳本應該自行處理。 – baky

+0

我不明白。你能否添加更多的信息你正在使用什麼組,以及爲什麼你想要顯示不同的幫助頁面? –

回答

1

這裏的風俗format_help方法:

import argparse 

def format_help(self, groups=None): 
    # self == parser 
    formatter = self._get_formatter() 

    # usage 
    formatter.add_usage(self.usage, self._actions, 
         self._mutually_exclusive_groups) 

    # description 
    formatter.add_text(self.description) 

    if groups is None: 
     groups = self._action_groups 

    # positionals, optionals and user-defined groups 
    for action_group in groups: 
     formatter.start_section(action_group.title) 
     formatter.add_text(action_group.description) 
     formatter.add_arguments(action_group._group_actions) 
     formatter.end_section() 

    # epilog 
    formatter.add_text(self.epilog) 

    # determine help from format above 
    return formatter.format_help() 

<your parser> 

args = parser.parse_args() 
# _action_groups[:2] are the default ones 
if args.help_a: 
    print(format_help(parser, [parser._action_groups[2]])) 
    parser.exit() 
if args.help_b: 
    print(format_help(parser, parser._action_groups[3:])) 
    parser.exit() 

樣品試驗

1444:~/mypy$ python stack40718566.py --help_a 
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2] 
         [--foo3 FOO3] 

Feature 1: 
    --foo1 FOO1 

1444:~/mypy$ python stack40718566.py --help_b 
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2] 
         [--foo3 FOO3] 

Feature 2: 
    --foo2 FOO2 

Feature 3: 
    --foo3 FOO3 

所以它就像默認format_help,但需要groups參數。它甚至可以替代ArgumentParser子類中的默認方法。

我們也可以創建一個自定義Help Action類,它的行爲與標準幫助類似,不同之處在於它需要某種group_list參數。但是這個解析後的動作更容易編碼和測試。

+0

謝謝,我也在思考類似的問題,比如覆蓋_ActionGroup類本身,它需要額外的參數'help_bucket',這意味着使用哪個幫助。但是這一個將會做到這一點,並且更簡單也更簡單。有一件事,使用默認顯示所有選項,這可以通過添加add_usage中僅需的操作輕鬆解決。再次感謝 – baky

0

我建議您不要嘗試做什麼。

You are solving a problem that isn't yours to solve.腳本的工作是返回使用信息。如果那是很多文字,那不是你的問題。你可以做的事,你正在做的事:將參數放入對用戶有意義的組中。但文本的數量是不是數據結構的問題,而是數據表示的問題

其次,您將得到以下一約定無人使用。通常有

man command 
command --help 
command subcommand --help 

任何其他的東西都會讓第一次使用者感到困惑。

此外,如果您有很多論證組,一個人總是需要諮詢--help以瞭解他們接下來要查詢哪些--help_*這可以令人沮喪給用戶時,你可以只是--help目前它的時候了。

如果您使用多個幫助頁面,您會阻止重複使用幫助文本。例如,搜索:多個頁面在手動切換時無法搜索。

正確的做法的方法是通過像less這樣的分頁器傳遞文本。這允許用戶通過網頁閱讀的文本頁面,通過它可以搜索(按/)或將其保存到文件:

command --help | less 

爲了方便一些命令,如git log,即使檢查output is an interactive terminalautomatically pass the output through less。這意味着

command --help > help.txt 

節省了幫助文件,而

command --help 

顯示分頁的幫助文本,和搜索。

所以我建議你在Windows和UNIX是

import os 
import sys 
import argparse 
import subprocess 


def less(data): 
    if sys.stdout.isatty(): 
     if os.name == 'posix': 
      cmd = "less" 
     elif os.name == 'nt': 
      cmd = "more" 

     process = subprocess.Popen([cmd], stdin=subprocess.PIPE) 

     try: 
      process.stdin.write(data) 
      process.communicate() 
     except IOError: 
      pass 
    else: 
     print data 


class MyArgumentParser(argparse.ArgumentParser): 
    def print_help(self, file=None): 
     less(self.format_help()) 
     self.exit() 


parser = MyArgumentParser(prog='PROG') 
group1 = parser.add_argument_group("Feature 1") 
group1.add_argument('--foo1') 
group2 = parser.add_argument_group("Feature 2") 
group2.add_argument('--foo2') 
group3 = parser.add_argument_group("Feature 3") 
group3.add_argument('--foo3') 
# parse some argument lists 
print parser.parse_args() 
+0

感謝您的詳細解答。關於你的上述評論提到人們無法查看哪些幫助使用,我將添加一個'help_all'選項,以便這不是一個問題。順便說一句,我仍然會看看如果類似於我的問題是可能的 – baky

+0

@hpaulj已發佈相同的解決方案。請看看 – baky