1. ホーム
  2. python

[解決済み] pythonのargparseでprefixのない排他的グループ引数を作るには?

2023-04-05 18:47:13

質問

Python2.7のargparseは、互いに排他的なグループのオプション引数(接頭辞付き)しか受け付けないのですか?

parser = argparse.ArgumentParser(prog='mydaemon')
action = parser.add_mutually_exclusive_group(required=True)
action.add_argument('--start', action='store_true', help='Starts %(prog)s daemon')
action.add_argument('--stop', action='store_true', help='Stops %(prog)s daemon')
action.add_argument('--restart', action='store_true', help='Restarts %(prog)s daemon')

$ mydaemon -h

usage: mydaemon [-h] (--start | --stop | --restart)

optional arguments:
  -h, --help  show this help message and exit
  --start     Starts mydaemon daemon
  --stop      Stops mydaemon daemon
  --restart   Restarts mydaemon daemon

argparseの引数を伝統的なunixのデーモン制御のように動作させる方法はありますか?

(start | stop | restart) and not (--start | --stop | --restart) ?

どのように解決するのですか?

のすべての能力およびオプションについて argparse のすべての能力およびオプションについて、あなたが望むような "canned"使用法の文字列を得ることはないと思います。

とはいえ、最初の投稿以来、サブパーサーを見たことがありますか?

ここに骨太の実装があります。

import argparse

parser = argparse.ArgumentParser(prog='mydaemon')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', help='Restarts %(prog)s daemon')

parser.parse_args()

これを -h オプションで実行すると、次のようになります。

usage: mydaemon [-h] {start,stop,restart} ...

positional arguments:
  {start,stop,restart}
    start               Starts mydaemon daemon
    stop                Stops mydaemon daemon
    restart             Restarts mydaemon daemon

この手法の利点のひとつは set_defaults を使用して、引数に直接関数をフックできることです。 また、"graceful" オプションで stoprestart :

import argparse

def my_stop(args):
    if args.gracefully:
        print "Let's try to stop..."
    else:
        print 'Stop, now!'

parser = argparse.ArgumentParser(prog='mydaemon')

graceful = argparse.ArgumentParser(add_help=False)
graceful.add_argument('-g', '--gracefully', action='store_true', help='tries to terminate the process gracefully')
sp = parser.add_subparsers()
sp_start = sp.add_parser('start', help='Starts %(prog)s daemon')
sp_stop = sp.add_parser('stop', parents=[graceful],
                    description='Stops the daemon if it is currently running.',
                    help='Stops %(prog)s daemon')
sp_restart = sp.add_parser('restart', parents=[graceful], help='Restarts %(prog)s daemon')

# Hook subparsers up to functions
sp_stop.set_defaults(func=my_stop)

# Uncomment when my_start() and 
# my_restart() are implemented
#
# sp_start.set_defaults(func=my_start)
# sp_restart.set_defaults(func=my_restart)

args = parser.parse_args()
args.func(args)

に対する "ヘルプ" メッセージを表示する。 stop :

$ python mydaemon.py stop -h
usage: mydaemon stop [-h] [-g]

Stops the daemon if it is currently running.

optional arguments:
  -h, --help        show this help message and exit
  -g, --gracefully  tries to terminate the process gracefully

"gracefully"を停止します。

$ python mydaemon.py stop -g
Let's try to stop...