ヘルプに表示されないように、argparseの引数を削除または無効にすることはできますか?どうやって?
新しい引数を追加するのは簡単です:
parser = argparse.ArgumentParser()
parser.add_argument('--arg1', help='Argument 1')
parser.add_argument('--arg2', help='A second one')
そして、「解決」競合ハンドラを指定することで、引数を新しい定義で上書きできることを知っています。
#In one script that should stand-alone and include arg1:
parser = argparse.ArgumentParser(conflict_handler='resolve')
parser.add_argument('--arg1', help='Argument 1')
parser.add_argument('--arg2', help='A second one')
#In another script with similar options
parser.add_argument('--arg1', help='New number 1')
しかし、これにはまだヘルプメッセージのarg1とparse_args
の結果が含まれています。
#Wishful thinking
#In another script with similar options, that shouldn't include arg1
parser.remove_argument('--arg1')
またはこれを達成するための別の合理的に簡単な方法?
また、引数が位置引数の場合、アプローチは異なりますか?
注:推奨された解析後のarg1
の削除に関する問題 here は、引数が引き続きヘルプに表示されることです
以下で言及するバグの問題にもかかわらず、resolve
の使用は可能な方法を示唆しています。これは、初心者や、パブリックAPIを使い続ける必要のある人向けではありません。
parser
には、アクション(引数)オブジェクトのリストがあります(_add_argument
_によって作成されます)。
2番目のパーサー定義を使用すると、その__actions
_リストは次のようになります。
_In [22]: parser._actions
Out[22]:
[_HelpAction(option_strings=['-h', '--help'], dest='help'...),
_StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None,
const=None, default=None, type=None, choices=None,
help='A second one', metavar=None),
_StoreAction(option_strings=['--arg1'], dest='arg1', nargs=None,
const=None, default=None, type=None, choices=None,
help='New number 1', metavar=None)]
_
resolve
で競合するアクションを追加すると、競合する既存のアクションが削除されます。詳細については、__handle_conflict_resolve
_メソッドを参照してください。しかし、私はそれをだまして、新しいアクションを追加せずにアクションを削除することができます。
_In [23]: parser._handle_conflict_resolve(None, [('--arg1',parser._actions[2])])
_
__actions
_を見て、_--arg1
_がなくなったことを確認します。
_In [24]: parser._actions
Out[24]:
[_HelpAction(option_strings=['-h', '--help'], dest='help',....),
_StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None,...)]
In [25]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2]
optional arguments:
-h, --help show this help message and exit
--arg2 ARG2 A second one
_
resolve
は、フラグ文字列が競合する可能性があるoptionals
を処理するだけです。そして、最初に競合するフラグを削除し、フラグが残っていない場合にのみ競合するアクションを削除します。したがって、短いオプションと長いオプションの両方がある場合は、特に注意してください。
そして、これはポジションのケースには対応していません。フラグはなく、dest
パラメータを共有する場合があります。 (ただし、アクションを追加していない限り、結果には1つしか表示されません)。
_In [27]: foo1 = parser.add_argument('foo',help='foo 1 positional')
In [28]: foo2 = parser.add_argument('foo',help='foo 2 positional')
In [29]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2] foo foo
positional arguments:
foo foo 1 positional
foo foo 2 positional
...
_
もう少し遊んでみると、これらの新しいポジションの1つを削除できるようです。
_In [33]: parser._actions[-1]
Out[33]: _StoreAction(option_strings=[], dest='foo',... help='foo 2 positional', metavar=None)
In [35]: foo2=parser._actions[-1]
In [36]: foo2.container._remove_action(foo2)
In [39]: parser.print_help()
usage: ipython3 [-h] [--arg2 ARG2] foo
positional arguments:
foo foo 1 positional
....
_
__actions[-2]
_を選択した場合、最初のfoo
を削除することになります。 _add_argument
_が返す値を変数に割り当てた場合、たとえば_foo1
_、_parser._actions
_リストの値を検索する代わりに、それを使用できます。対話型シェル(私はIPythonを使用しています)でサンプルパーサーを実行し、これらのオブジェクトを確認すると役立つ場合があります。
繰り返しますが、これは簡単な例で機能するようですが、より複雑なもの(または本番用)で使用する場合は、慎重なテストが必要です。
このトピックは、数年前にPythonバグ/問題で取り上げられました。
http://bugs.python.org/issue19462Add remove_argument() method to argparse.ArgumentParser
私は完全な除去の難しさについて話し合い、いくつかの代替案を提案しました。 _argparse.SUPPRESS
_は、ヘルプを非表示にするために使用できます。 optionals
は、不要な場合は無視できます。 positionals
の方が扱いにくいですが、属性(nargs
およびdefault
)を調整することをお勧めします。しかし、久しぶりなので、これらの投稿を確認する必要があります。
=============================
_@2rs2ts
_の問題に興味がありました(コメントを参照)。
パーサーを作成し、それを別のパーサーの親として使用しました(サブパーサーメカニズムを使用する必要はありません)。次に、1つのパーサーから引数を削除し、他のパーサーの変更を調べました。
1つの引数で親パーサーを作成します。
_In [59]: p=argparse.ArgumentParser()
In [60]: p.add_argument('--foo')
Out[60]: _StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
_
parents
で別のものを作成:
_In [61]: p1=argparse.ArgumentParser(parents=[p],add_help=False)
In [62]: p1._actions
Out[62]:
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
_
2番目のアクションは両方のパーサーで同じであることに注意してください(同じID)。 parents
が元の_--foo
_アクションへの参照をコピーしただけで、コピーは作成されませんでした。
_In [63]: id(p._actions[1])
Out[63]: 3000108652
In [64]: id(p1._actions[1])
Out[64]: 3000108652
_
ここで、以前に解決したトリックを使用して、1つのパーサーから '--foo'を削除します。
_In [65]: p1._handle_conflict_resolve(None,[('--foo',p1._actions[1])])
In [66]: p1._actions
Out[66]: [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None)]
_
'--foo'は_p1
_リストから削除されましたが、p
リストにはまだ残っています。しかし、_option_strings
_は現在空です。
_In [67]: p._actions
Out[67]:
[_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None),
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)]
_
resolve
コードは、競合する_option_strings
_を_--foo
_アクションから削除し、次に_p1._actions
_リストから削除しました。ただし、_option_strings
_参照の_p1
_を変更すると、p
参照も変更されました。
argparse
は、いくつかの方法でpositionals
とoptionals
を区別しますが、解析で最も頻繁に使用されるのは、_option_strings
_属性が空かどうかを調べることですない。この属性を空にすることで、resolve
はoptional
をpositional
に効果的に変換しました。
おっと、私の記憶は本来あるべきものではありません。:) 1年前、parents
とresolve
に関する同様の質問に答えました
https://stackoverflow.com/a/25821043/901925 _argparse conflict resolver for options in subcommands turns keyword argument into positional argument
_
Argparseの引数を削除または無効にして、ヘルプに表示されないようにすることはできますか?
次のように、引数を追加するときにhelp
をargparse.SUPPRESS
に設定します。
parser.add_argument('--arg1', help=argparse.SUPPRESS)
これにより、引数がデフォルトのヘルプ出力に表示されなくなります。
Argparseオプションを削除する関数:
def remove_options(parser, options):
for option in options:
for action in parser._actions:
if vars(action)['option_strings'][0] == option:
parser._handle_conflict_resolve(None,[(option,action)])
break
Hpauljの回答は素晴らしいですが、私の場合、parser._remove_action(action)
だけを使用すると、「位置引数」から削除されず、削除されたアクションを支援しました。私の回避策は、_action_group
からも削除することでした。
def remove_option(parser, arg):
for action in parser._actions:
if (vars(action)['option_strings']
and vars(action)['option_strings'][0] == arg) \
or vars(action)['dest'] == arg:
parser._remove_action(action)
for action in parser._action_groups:
vars_action = vars(action)
var_group_actions = vars_action['_group_actions']
for x in var_group_actions:
if x.dest == arg:
var_group_actions.remove(x)
return