私はargparse
をPythonできるプログラム-process
、-upload
または両方:
parser = argparse.ArgumentParser(description='Log archiver arguments.')
parser.add_argument('-process', action='store_true')
parser.add_argument('-upload', action='store_true')
args = parser.parse_args()
プログラムは、少なくとも1つのパラメーターがなければ意味がありません。少なくとも1つのパラメーターを選択するようにargparse
を構成するにはどうすればよいですか?
更新:
コメントに従ってください:少なくとも1つのオプションでプログラムをパラメーター化するPythonicの方法は何ですか?
if not (args.process or args.upload):
parser.error('No action requested, add -process or -upload')
args = vars(parser.parse_args())
if not any(args.values()):
parser.error('No arguments provided.')
「または両方」の部分ではない場合(最初はこれを見逃していました)、次のようなものを使用できます。
parser = argparse.ArgumentParser(description='Log archiver arguments.')
parser.add_argument('--process', action='store_const', const='process', dest='mode')
parser.add_argument('--upload', action='store_const', const='upload', dest='mode')
args = parser.parse_args()
if not args.mode:
parser.error("One of --process or --upload must be given")
ただし、代わりに subcommands を使用することをお勧めします。
私はこれが汚れとして古いことを知っていますが、1つのオプションを必要とするが複数の(XOR)を禁止する方法は次のとおりです:
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-process', action='store_true')
group.add_argument('-upload', action='store_true')
args = parser.parse_args()
print args
出力:
>opt.py
usage: multiplot.py [-h] (-process | -upload)
multiplot.py: error: one of the arguments -process -upload is required
>opt.py -upload
Namespace(process=False, upload=True)
>opt.py -process
Namespace(process=True, upload=False)
>opt.py -upload -process
usage: multiplot.py [-h] (-process | -upload)
multiplot.py: error: argument -process: not allowed with argument -upload
argparse
を使用します(これは無視します)コマンドラインで実行する場合、暗黙的な要件もいくつかあります。
docopt
(ファイルmanagelog.py
):"""Manage logfiles
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> Password
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
"""
if __== "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
実行してみてください:
$ python managelog.py
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
ヘルプを表示する:
$ python managelog.py -h
Manage logfiles
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> P managelog.py [options] upload -- <logfile>...
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
そしてそれを使用します:
$ python managelog.py -V -U user -P secret upload -- alfa.log beta.log
{'--': True,
'--pswd': 'secret',
'--user': 'user',
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': False,
'upload': True}
short.py
さらに短いバリアントもあります。
"""Manage logfiles
Usage:
short.py [options] (process|upload)... -- <logfile>...
short.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> Password
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
"""
if __== "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
使用方法は次のとおりです。
$ python short.py -V process upload -- alfa.log beta.log
{'--': True,
'--pswd': None,
'--user': None,
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': 1,
'upload': 1}
「プロセス」および「アップロード」キーのブール値の代わりにカウンターがあることに注意してください。
結局のところ、これらの単語の重複を防ぐことはできません。
$ python short.py -V process process upload -- alfa.log beta.log
{'--': True,
'--pswd': None,
'--user': None,
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': 2,
'upload': 1}
優れたコマンドラインインターフェイスを設計することは、時には困難な場合があります。
コマンドラインベースのプログラムには複数の側面があります。
argparse
は多くを提供しますが、可能なシナリオを制限し、非常に複雑になる可能性があります。
docopt
を使用すると、読みやすさを維持し、高度な柔軟性を提供しながら、物事がはるかに短くなります。辞書から解析された引数を取得し、いくつかの変換(整数への変換、ファイルを開くなど)を手動で(または schema
と呼ばれる他のライブラリによって)行う場合、docopt
コマンドライン解析に適しています。
これを行う最良の方法は、python inbuilt module add_mutually_exclusive_groupを使用することです。
parser = argparse.ArgumentParser(description='Log archiver arguments.')
group = parser.add_mutually_exclusive_group()
group.add_argument('-process', action='store_true')
group.add_argument('-upload', action='store_true')
args = parser.parse_args()
コマンドラインで1つの引数のみを選択する場合は、グループの引数としてrequired = Trueを使用します。
group = parser.add_mutually_exclusive_group(required=True)
pythonプログラムを少なくとも1つのパラメーターで実行する必要がある場合は、does n'tオプションプレフィックス(デフォルトでは-または-)を持つ引数を追加します。 set nargs=+
(1つ以上の引数が必要です)このメソッドの問題は、引数を指定しないと、argparseが "引数が少なすぎます"エラーを生成し、ヘルプメニューを出力しないことです。その機能が必要な場合は、コードでそれを行う方法があります
import argparse
parser = argparse.ArgumentParser(description='Your program description')
parser.add_argument('command', nargs="+", help='describe what a command is')
args = parser.parse_args()
I 思考オプションプレフィックスを付けて引数を追加すると、nargsはオプションだけでなく引数パーサー全体を制御します。 (つまり、--option
フラグにnargs="+"
がある場合、--option
フラグには少なくとも1つの引数が必要です。option
にnargs="+"
がある場合、全体で少なくとも1つの引数が必要です。)
http://bugs.python.org/issue11588 このようなケースを処理するためにmutually_exclusive_group
コンセプトを一般化する方法を模索しています。
この開発でargparse.py
、 https://github.com/hpaulj/argparse_issues/blob/nested/argparse.py を書くことができます:
parser = argparse.ArgumentParser(prog='PROG',
description='Log archiver arguments.')
group = parser.add_usage_group(kind='any', required=True,
title='possible actions (at least one is required)')
group.add_argument('-p', '--process', action='store_true')
group.add_argument('-u', '--upload', action='store_true')
args = parser.parse_args()
print(args)
次のhelp
を生成します。
usage: PROG [-h] (-p | -u)
Log archiver arguments.
optional arguments:
-h, --help show this help message and exit
possible actions (at least one is required):
-p, --process
-u, --upload
これは、「-u」、「-up」、「-proc --up」などの入力を受け入れます。
エラーメッセージをより明確にする必要がありますが、最終的に https://stackoverflow.com/a/6723066/901925 のようなテストを実行します。
usage: PROG [-h] (-p | -u)
PROG: error: some of the arguments process upload is required
私は疑問に思う:
パラメーターkind='any', required=True
は十分にクリアですか(グループのいずれかを受け入れます。少なくとも1つが必要です)。
使用法(-p | -u)
は明確ですか?必須の相互相互排他グループは同じものを生成します。代替の表記法はありますか?
phihag's
単純なテストよりも直感的なこのグループを使用していますか?
おそらくサブパーサーを使用しますか?
import argparse
parser = argparse.ArgumentParser(description='Log archiver arguments.')
subparsers = parser.add_subparsers(dest='subparser_name', help='sub-command help')
parser_process = subparsers.add_parser('process', help='Process logs')
parser_upload = subparsers.add_parser('upload', help='Upload logs')
args = parser.parse_args()
print("Subparser: ", args.subparser_name)
--help
が表示されます:
$ python /tmp/aaa.py --help
usage: aaa.py [-h] {process,upload} ...
Log archiver arguments.
positional arguments:
{process,upload} sub-command help
process Process logs
upload Upload logs
optional arguments:
-h, --help show this help message and exit
$ python /tmp/aaa.py
usage: aaa.py [-h] {process,upload} ...
aaa.py: error: too few arguments
$ python3 /tmp/aaa.py upload
Subparser: upload
これらのサブパーサーに追加のオプションを追加することもできます。また、dest='subparser_name'
を使用する代わりに、特定のサブコマンドで直接呼び出される関数をバインドすることもできます(ドキュメントを参照)。
Append_constを使用してアクションのリストを作成し、リストにデータが入力されていることを確認します。
parser.add_argument('-process', dest=actions, const="process", action='append_const')
parser.add_argument('-upload', dest=actions, const="upload", action='append_const')
args = parser.parse_args()
if(args.actions == None):
parser.error('Error: No actions requested')
定数内でメソッドを直接指定することもできます。
def upload:
...
parser.add_argument('-upload', dest=actions, const=upload, action='append_const')
args = parser.parse_args()
if(args.actions == None):
parser.error('Error: No actions requested')
else:
for action in args.actions:
action()
これは目的を達成し、これは自動生成されたargparse --help
出力。これは、ほとんどの正気なプログラマが望むものです(オプションの引数でも機能します)。
parser.add_argument(
'commands',
nargs='+', # require at least 1
choices=['process', 'upload'], # restrict the choice
help='commands to execute'
)
これに関する公式ドキュメント: https://docs.python.org/3/library/argparse.html#choices