2013-08-27 58 views
20

一起使用我使用argparse接受命令行輸入並且還生成幫助文本。我想使用ArgumentDefaultsHelpFormatter作爲formatter_class,但是這可以防止我也使用RawDescriptionHelpFormatter,這將允許我將自定義格式添加到我的描述或epilog。ArgumentParser epilog和描述格式與ArgumentDefaultsHelpFormatter

除了編寫代碼來爲我自己生成默認值的文本之外,是否有一種明智的方法來實現這一點?根據argparse文檔,ArgumentParser的所有內部都被視爲實現細節,而不是公共API,因此子分類不是一個有吸引力的選擇。

回答

28

我只是嘗試了多重繼承的方式,它的工作原理:

class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter): 
    pass 

parser = argparse.ArgumentParser(description='test\ntest\ntest.', 
           epilog='test\ntest\ntest.', 
           formatter_class=CustomFormatter) 

如果這些階級的內部雖然改變這可能會斷裂。

+0

以這種方式進行子類化並不依賴於內部。如果多重繼承現在起作用,它應該在將來的所有變化中使用。正如我的解決方案所示,這兩個類正在改變不同的格式化方法。 – hpaulj

+0

使用此多重繼承的另一個示例:http://stackoverflow.com/questions/23567393/pythons-argh-library-preserve-docstring-formatting-in-help-message/23583350#23583350 – hpaulj

+0

@hpaulj格式化程序方法不是公共API的一部分。來自'argparse.HelpFormatter'的文檔字符串:'只有這個類的名字被認爲是一個公共API。該類提供的所有方法都被視爲一個實現細節。這兩個類都可以完全重寫。 – timdiels

1

我不明白爲什麼繼承HelpFormatter應該是一個問題。這並沒有搞亂ArgumentParser的內部。該文檔具有自定義ActionType類(或函數)的示例。如果需要,我將'there are four such classes'一行作爲邀請編寫自己的HelpFormatter。

提供的HelpFormatter子類進行了非常簡單的更改,只改變了一個函數。所以他們可以很容易地複製或改變。

RawDescription只是改變:

def _fill_text(self, text, width, indent): 
    return ''.join(indent + line for line in text.splitlines(keepends=True)) 

理論上它可以在不改變API改變,但它不太可能。

的默認格式只是改變:

def _get_help_string(self, action): 
    help = action.help 
    if '%(default)' not in action.help: 
     if action.default is not SUPPRESS: 
      defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] 
      if action.option_strings or action.nargs in defaulting_nargs: 
       help += ' (default: %(default)s)' 
    return help 

您可以通過只包括所有參數的幫助線%(default)s獲得同樣的效果。與Raw子類相反,這只是一個便利課程。它不會讓您更好地控制格式。