290

argparseコマンドライン引数/オプションを処理するために使用するプログラムがあると仮定します。以下は、「ヘルプ」メッセージを出力します。

./myprogram -h

また:

./myprogram --help

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

4

18 に答える 18

340

この回答は、 GoogleグループのStevenBethardからのものです。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()デフォルトではstdoutに出力されることに注意してください。init_jsが示唆しているように、を使用parser.print_help(sys.stderr)してstderrに出力します。

于 2010-10-28T12:23:33.193 に答える
79

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

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

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

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

于 2015-03-27T04:03:12.090 に答える
39

argparseを使用すると、次を使用できますArgumentParser.print_usage()

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.print_usage(file=None)

ArgumentParserコマンドラインでを呼び出す  方法の簡単な説明を印刷します。の場合、fileが想定されます。Nonesys.stdout

于 2015-03-28T01:50:40.200 に答える
31

以下で説明するように、(サブ)パーサーのデフォルト関数を関連付ける場合はadd_subparsers、それをデフォルトアクションとして追加するだけです。

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

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

于 2016-11-15T15:43:12.873 に答える
23

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

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

スクリプトが引数なしで実行された場合、parse_args()はエラーを報告します。

于 2016-06-17T08:10:59.003 に答える
21

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

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

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

于 2017-11-22T16:59:52.933 に答える
11

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

import argparse

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

お気づきかもしれませんが、ファイル内parser.exitの唯一の理由がインポート行を保存するため、主にそのようにしてsysいます...

于 2015-09-28T13:19:56.720 に答える
6

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

最初のものは、自明で、クリーンで、pythonicです:

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

2つ目は少しハッカーです。空のリストがあるという以前に評価された事実と同等のものを組み合わせるとFalse、次のようになります。True == 1False == 0

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

角かっこが多すぎるかもしれませんが、前の引数の選択が行われたかどうかはかなり明確です。

_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
于 2018-07-25T09:41:59.120 に答える
5
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=64, message="\nSomething went wrong, --example condition was not set\n")


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

呼び出し例:

$ python3〜/ helloworld.py; エコー$?
使用法:helloworld.py [-h] [--example]

 argparserベースのPythonファイルの例

オプションの引数:
  -h、-helpこのヘルプメッセージを表示して終了します
  --例引数の例

何かがうまくいかなかった、-例の条件が設定されていなかった
64
$ python3〜/ helloworld.py --example; エコー$?
0
于 2017-12-14T01:01:08.193 に答える
2

だから本当に簡単な答えのために。ほとんどの場合、argparseでは、何かを実行する関数を呼び出すために、パラメーターが設定されているかどうかを確認しています。

パラメータがない場合は、最後に出力してヘルプを印刷します。シンプルで動作します。

import argparse
import sys
parser = argparse.ArgumentParser()

group = parser.add_mutually_exclusive_group()
group.add_argument("--holidays", action='store_true')
group.add_argument("--people", action='store_true')

args=parser.parse_args()
if args.holidays:
    get_holidays()
elif args.people:
    get_people()
else:
    parser.print_help(sys.stderr)
于 2021-07-09T15:03:07.563 に答える
2

ここでの回答のほとんどは、などの別のモジュールをsysインポートするか、オプションの引数を使用する必要がありました。argparseのみを使用し、必要な引数を使用し、可能であれば例外をキャッチせずに機能する回答を見つけたかったのです。私は次のようになりました:

import argparse

if __name__ == '__main__':

    arg_parser = argparse.ArgumentParser(add_help=False)
    arg_parser.add_argument('input_file', type=str, help='The path to the input file.')
    arg_parser.add_argument('output_file', type=str, help='The path to the output file.')
    arg_parser.add_argument('-h','--help', action='store_true', help='show this help message and exit')
    arg_parser.usage = arg_parser.format_help()
    args = arg_parser.parse_args()

主なアイデアはformat_help、usageステートメントにヘルプ文字列を提供するために関数を使用することでした。呼び出しでにを設​​定add_helpすると、特定の状況でヘルプステートメントが2回出力されなくなります。ただし、ヘルプメッセージにオプションのヘルプ引数を表示するには、設定後に通常のヘルプメッセージを模倣するオプションのヘルプ引数の引数を作成する必要がありました。このアクションは、ヘルプメッセージを出力するときに、ヘルプメッセージがパラメーターのような値を入力しないように、ヘルプ引数で設定されます。FalseArgumentParser()Falsestore_trueHELP

于 2022-02-03T15:18:49.500 に答える
1

これを行う別の方法があります。特定のパラメーターが渡された場合にヘルプを表示する柔軟なものが必要な場合は、競合する引数がまったくないか、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 ...

乾杯!

于 2017-12-20T17:27:00.680 に答える
1

私は物事をできるだけシンプルに保つのが好きです、これはうまくいきます:

#!/usr/bin/env python3
Description = """Tool description"""
Epilog  = """toolname.py -a aflag -b bflag  with these combined it does blah"""
arg_parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter,
    description=Description, 
    epilog=Epilog,
)
    try:
        if len(sys.argv) == 1:
            arg_parser.print_help()
    except Exception as e:
        print(e)

いくつかの例を含めるのは常に良いことなので、これが私のすべてのツールを開始する方法です

于 2020-11-11T22:25:46.107 に答える
1

メソッドを呼び出すときはadd_subparsers、次のように、最初の位置引数をに保存し、dest=argparseが初期化された後に値を確認します。

subparsers = parser.add_subparsers(dest='command')

そして、この変数を確認してください。

if not args.command:
    parser.print_help()
    parser.exit(1)  # If exit() - exit code will be zero (no error)

完全な例:

#!/usr/bin/env python

""" doc """

import argparse
import sys

parser = argparse.ArgumentParser(description=__doc__)
subparsers = parser.add_subparsers(dest='command',
                                   help='List of commands')

list_parser = subparsers.add_parser('list',
                                    help='List contents')
list_parser.add_argument('dir', action='store',
                         help='Directory to list')

create_parser = subparsers.add_parser('create',
                                      help='Create a directory')
create_parser.add_argument('dirname', action='store',
                           help='New directory to create')
create_parser.add_argument('--read-only', default=False, action='store_true',
                           help='Set permissions to prevent writing to the directory')

args = parser.parse_args()

if not args.command:
    parser.print_help()
    parser.exit(1)

print(vars(args))  # For debug
于 2021-02-14T05:12:28.457 に答える
0

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

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

Pythonnargsを参照する

于 2017-04-12T19:50:06.443 に答える
0

コマンドがユーザーが何らかのアクションを選択する必要があるものである場合は、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ができることを知っています

于 2019-08-22T11:22:10.190 に答える
0

これは良くありません(また、すべてのエラーをインターセプトするため)が、次のようになります。

def _error(parser):
    def wrapper(interceptor):
        parser.print_help()

        sys.exit(-1)

    return wrapper

def _args_get(args=sys.argv[1:]):
    parser = argparser.ArgumentParser()

    parser.error = _error(parser)

    parser.add_argument(...)
    ...

クラスのerror関数の定義は次のとおりです。ArgumentParser

ご覧のとおり、次の署名には2つの引数があります。ただし、クラス外の関数は最初の引数について何も知りませんself。大まかに言えば、この引数はクラス用だからです。

def _error(self, message):
    self.print_help()

    sys.exit(-1)

def _args_get(args=sys.argv[1:]):
    parser = argparser.ArgumentParser()

    parser.error = _error
    ...

出力します:

"AttributeError: 'str' object has no attribute 'print_help'"

次のように呼び出すことで、関数にparserself)を渡すことができます。_error

def _error(self, message):
    self.print_help()

    sys.exit(-1)

def _args_get(args=sys.argv[1:]):
    parser = argparser.ArgumentParser()

    parser.error = _error(parser)
    ...

ただし、今すぐプログラムを終了したくない場合は、次のように返します。

def _error(parser):
    def wrapper():
        parser.print_help()

        sys.exit(-1)

    return wrapper

それにもかかわらず、parserそれが変更されたことを知りません。したがって、エラーが発生すると、その原因が出力されます(ちなみに、これはローカライズされた翻訳です)。だからそれを傍受します:

def _error(parser):
    def wrapper(interceptor):
        parser.print_help()

        sys.exit(-1)

    return wrapper

さて、エラーが発生したとき、parserその原因を印刷し、それを傍受し、それを見て、そして...捨てます。

于 2020-03-16T22:47:55.883 に答える
0

それが私が思いついたものです:

import sys
import argparse


HelpFlags = ('help', '--help', '-h', '/h', '?', '/?', )


class ArgParser (argparse.ArgumentParser):
    
    def __init__(self, *args, **kws):
        super().__init__(*args, **kws)
    
    def parse_args(self, args=None, namespace=None):
        
        if args is None:
            args = sys.argv[1:]
        
        if len(args) < 1 or (args[0].lower() in HelpFlags):
            self.print_help(sys.stderr)
            sys.exit()
        
        return super().parse_args(args, namespace)
于 2022-01-06T18:27:08.960 に答える