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

StackOverflow https://stackoverflow.com/questions/4042452

  •  27-09-2019
  •  | 
  •  

質問

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

./myprogram -h

または:

./myprogram --help

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

役に立ちましたか?

解決

この回答は 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) 標準エラー出力に出力します。

他のヒント

の代わりにクラスを書いて、試してみる/除く

の代わりに使用することができます
try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)

逆さまには、ワークフローが明確であり、あなたはスタブクラスを必要としないことです。欠点は、最初の「用法」行が重複して印刷されていることである。

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

あなたができる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)

スクリプトが実行するように指定する必要があります引数を持っている場合 - 以下のようにArgumentParserのための必要のパラメータを使用します。 -

parser.add_argument('--foo', required=True)
スクリプトは引数なしで実行された場合、

parse_args()はエラーを報告します。

(サブ)パーサーのあなた関連付けるデフォルトの機能として、 add_subparsers を、あなたは、単にデフォルトのアクションとして追加することができます:

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

のtry-を除き、あなたが原因位置引数の欠落に例外を発生させる場合を追加します。

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

import argparse

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

あなたはparser.exitに気づくこと - それは、ファイル内sysのための唯一の理由...

だった場合は、インポートラインを節約するので、私は主にそのようにそれを行います

きれいな解決策が何もコマンドラインで与えられなかった場合は、手動でデフォルト引数を渡すことになります:

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))

この引数には、O / Wと呼ばれます。

場合は、完全なヘルプ(ない短い用法)を印刷します

仕事をすることができますsys.argv[1:]とワンライナー(コマンドライン引数を参照するために非常に一般的なPythonのイディオム、sys.argv[0]スクリプトの名前である)のペアがあります。

最初のものは自明、クリーンでニシキヘビである

args = parser.parse_args(None if sys.argv[1:] else ['-h'])
もう一つは少しhackierです。

:空のリストは、あなたがこれを取得FalseTrue == 1等価とFalse == 0であることを以前に評価事実を組み合わせます
args = parser.parse_args([None, ['-h']][not sys.argv[1:]])

たぶん、あまりにも多くのブラケットが、前の引数の選択がなされた場合にはかなり明確ます。

_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
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 __name__ == '__main__':
    main()  # pragma: no cover

例呼び出します:

$ python3 ~/helloworld.py; echo $?
usage: helloworld.py [-h] [--example]

 Example argparser based python file

optional arguments:
  -h, --help  show this help message and exit
  --example   Example Argument

I just don't know what went wrong, maybe missing --example condition?
128
$ python3 ~/helloworld.py --example; echo $?
0

NARGSであなたの位置引数を設定し、位置引数が空であるかどうかを確認します。

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

リファレンス PythonのNARGSする

あなたが特定のparamsを渡された場合、ヘルプを表示する柔軟な何かが必要な場合は、ここ1相反する引数より全て以上でどれも、それを行うための別の方法ではありません。

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 ...

乾杯!

あなたのコマンドは、ユーザーが何らかのアクションを選択する必要がある何かである場合は、

、その後、必要=真の。

と相互に排他的なグループのを使用

これは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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top