web-dev-qa-db-ja.com

引数なしでスクリプトが呼び出されたときにpython argparseでヘルプメッセージを表示する

これは単純なものかもしれません。 argparseを使用してコマンドライン引数/オプションを処理するプログラムがあると仮定します。以下は「ヘルプ」メッセージを出力します:

./myprogram -h

または:

./myprogram --help

ただし、引数を指定せずにスクリプトを実行すると、何も実行されません。私がやりたいのは、引数なしで呼び出されたときに使用法メッセージを表示することです。どうやって?

193
musashiXXX

この答えは、Steven Bethard Googleグループ からのものです。 Googleアカウントを持たない人がアクセスしやすくするために、ここに再投稿しています。

errorメソッドのデフォルトの動作をオーバーライドできます。

import argparse
import sys

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)

parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()

上記のソリューションは、errorメソッドがトリガーされるたびにヘルプメッセージを出力することに注意してください。たとえば、test.py --blahが有効なオプションでない場合、--blahはヘルプメッセージも出力します。

コマンドラインで引数が指定されていない場合にのみヘルプメッセージを出力する場合は、おそらくこれが最も簡単な方法です。

import argparse
import sys

parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)
args=parser.parse_args()

parser.print_help()はデフォルトで標準出力に出力されることに注意してください。 init_jsが示唆する のように、parser.print_help(sys.stderr)を使用してstderrに出力します。

243
unutbu

クラスを記述する代わりに、try/exceptを代わりに使用できます

try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)

利点は、ワークフローがより明確になり、スタブクラスが不要になることです。欠点は、最初の「使用」行が2回印刷されることです。

これには、少なくとも1つの必須引数が必要です。必須の引数がない場合、コマンドラインでゼロの引数を指定することは有効です。

47
vacri

Argparseでできること:

parser.argparse.ArgumentParser()
#parser.add_args here

#sys.argv includes a list of elements starting with the program
if len(sys.argv) < 2:
    parser.print_usage()
    sys.exit(1)
20
cgseller

スクリプトを実行するために指定する必要がある引数がある場合は、以下に示すように、ArgumentParserに必須パラメーターを使用します。

parser.add_argument('--foo', required=True)

引数なしでスクリプトを実行すると、parse_args()はエラーを報告します。

15
pd321

add_subparsers で説明されているように、(サブ)パーサーのデフォルト関数を関連付ける場合、単純にデフォルトアクションとして追加できます。

parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)

位置引数が欠落しているために例外が発生する場合は、try-exceptを追加します。

13
AManOfScience

ここに私のバージョンを山に投げます:

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
    parser.print_help()
    parser.exit(1)

parser.exitに気付くかもしれません-ファイル内のsysの唯一の理由である場合、インポート行を保存するので、私は主にそのようにします...

9
pauricthelodger

最もクリーンなソリューションは、コマンドラインで何も指定されていない場合、デフォルトの引数を手動で渡すことです。

parser.parse_args(args=None if sys.argv[1:] else ['--help'])

完全な例:

import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('--Host', default='localhost', help='Host to connect to')
# parse arguments
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])

# use your args
print("connecting to {}".format(args.Host))

これは、引数なしで呼び出された場合、完全なヘルプ(短い使用法ではなく)を出力します。

6
Ievgen Popovych

sys.argv[1:](コマンドライン引数を参照する非常に一般的なPythonのイディオム、sys.argv[0]スクリプト名)を備えた一対のワンライナーがあり、ジョブを実行できます。

1つ目は、説明のつかない、クリーンでPythonicです。

args = parser.parse_args(None if sys.argv[1:] else ['-h'])

2番目は少しハッカーです。空のリストがFalseであるという以前に評価された事実とTrue == 1およびFalse == 0の同等物を組み合わせて、これを取得します。

args = parser.parse_args([None, ['-h']][not sys.argv[1:]])

角括弧が多すぎるかもしれませんが、前の引数を選択した場合はかなり明確です。

_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
2
Nuno André
parser.print_help()
parser.exit()

parser.exitメソッドは、status(戻りコード)およびmessage値(末尾の改行を自分で含めてください!)も受け入れます。

意見を述べた例、:)

#!/usr/bin/env python3

""" Example argparser based python file
"""

import argparse

ARGP = argparse.ArgumentParser(
    description=__doc__,
    formatter_class=argparse.RawTextHelpFormatter,
)
ARGP.add_argument('--example', action='store_true', help='Example Argument')


def main(argp=None):
    if argp is None:
        argp = ARGP.parse_args()  # pragma: no cover

    if 'soemthing_went_wrong' and not argp.example:
        ARGP.print_help()
        ARGP.exit(status=128, message="\nI just don't know what went wrong, maybe missing --example condition?\n")


if __== '__main__':
    main()  # pragma: no cover

呼び出しの例:

 $ python3〜/ helloworld.py; echo $?
 usage:helloworld.py [-h] [--example] 
 
 argparserベースのpython file 
 
 optional arguments:
 -h、--helpこのヘルプメッセージを表示して終了
 --example引数の例
 
 --example conditionが欠落している可能性がありますか?
 128 
 $ python3〜/ helloworld.py --example; echo $?
 0 
1
ThorSummoner

コマンドがユーザーが何らかのアクションを選択する必要がある場合、相互に排他的なグループwith required = Trueを使用します。

これは、pd321によって与えられる答えの一種の拡張です。

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--batch", action='store', type=int,  metavar='pay_id')
group.add_argument("--list", action='store_true')
group.add_argument("--all", action='store_true', help='check all payments')

args=parser.parse_args()

if args.batch:
    print('batch {}'.format(args.batch))

if args.list:
    print('list')

if args.all:
    print('all')

出力:

$ python3 a_test.py
使用法:a_test.py [-h](--batch pay_id | --list | --all)
a_test.py:エラー:引数の1つ--batch --list --allが必要です

これは基本的なヘルプのみを提供します。そして、他の答えのいくつかはあなたに完全な助けを与えます。しかし、少なくともユーザーはできることを知っています-h

0
Tim Bray

特定のパラメーターが渡された場合にヘルプを表示したい場合に柔軟な何かが必要な場合は、別の方法があります。

import argparse
import sys

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--days', required=False,  help="Check mapped inventory that is x days old", default=None)
    parser.add_argument('-e', '--event', required=False, action="store", dest="event_id",
                        help="Check mapped inventory for a specific event", default=None)
    parser.add_argument('-b', '--broker', required=False, action="store", dest="broker_id",
                        help="Check mapped inventory for a broker", default=None)
    parser.add_argument('-k', '--keyword', required=False, action="store", dest="event_keyword",
                        help="Check mapped inventory for a specific event keyword", default=None)
    parser.add_argument('-p', '--product', required=False, action="store", dest="product_id",
                        help="Check mapped inventory for a specific product", default=None)
    parser.add_argument('-m', '--metadata', required=False, action="store", dest="metadata",
                        help="Check mapped inventory for specific metadata, good for debugging past tix", default=None)
    parser.add_argument('-u', '--update', required=False, action="store_true", dest="make_updates",
                        help="Update the event for a product if there is a difference, default No", default=False)
    args = parser.parse_args()

    days = args.days
    event_id = args.event_id
    broker_id = args.broker_id
    event_keyword = args.event_keyword
    product_id = args.product_id
    metadata = args.metadata
    make_updates = args.make_updates

    no_change_counter = 0
    change_counter = 0

    req_arg = bool(days) + bool(event_id) + bool(broker_id) + bool(product_id) + bool(event_keyword) + bool(metadata)
    if not req_arg:
        print("Need to specify days, broker id, event id, event keyword or past tickets full metadata")
        parser.print_help()
        sys.exit()
    Elif req_arg != 1:
        print("More than one option specified. Need to specify only one required option")
        parser.print_help()
        sys.exit()

    # Processing logic here ...

乾杯!

0
radtek

Nargsを使用して位置引数を設定し、位置引数が空かどうかを確認します。

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='?')
args = parser.parse_args()
if not args.file:
    parser.print_help()

リファレンス Python nargs

0
zerocog