5

argparse.ArgumentParser オブジェクトのグローバル オプションを使用して、サブコマンドのデフォルト値をオーバーライド/拡張​​できるようにしたいと考えています。

たとえば、次のおもちゃの例では、表示されるヘルプにグローバルな更新が反映されます。

import argparse
import os
import sys

# Global parser and options.
parser = argparse.ArgumentParser(
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument("--user", 
                    dest="user", 
                    default=os.environ.get("USER"),
                    help="Override the setting of the $USER variable.")

# Sub-command parser and options.
subparsers = parser.add_subparsers()

command = subparsers.add_parser(
    "command",
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

command.add_argument("--config",
                     dest="config",
                     default="~%s/config" % os.environ.get("USER"),
                     help="The config file.")

options = parser.parse_args()

理想的には、これをヘルプモードで実行すると、

> python example.py --user thing command --help
usage: example.py command [-h] [--config CONFIG]

optional arguments:
  -h, --help       show this help message and exit
  --config CONFIG  The config file. (default: ~thing/config)

つまり、設定ファイルのパスはユーザー固有のものです。デフォルトの構成を に変更"~%(user)s/config"し、オプションの名前空間を使用して実行時にこれを解決できることを認識していますが、ヘルプをより明確にしたいと考えています。

別の解決策は、引数を一度解析してグローバルオプションを取得することです。つまり、

if "--help" in sys.argv:

    # Parse the command minus the help to obtain the global options. 
    args = sys.argv[1:]
    args.remove("--help")

    # Update the defaults with the global options.
    options = parser.parse_args(args) 
    command.set_defaults(config="~%s/config" % options.user)

    # Re-parse the options.
    parser.parse_args()

これはややハッキーに思えますが。より良いアプローチ/ソリューションはありますか?

4

2 に答える 2

4

グローバル オプションを定義した後、サブコマンドを定義する前に、 を呼び出しparse_known_argsて の値を調べます--user。次に、コマンド ラインのすべてのオプションを解析するために呼び出す前に、 の値を使用--userして のデフォルトを定義し、サブパーサー コマンドの定義を終了します。--configparse_args

これは別の方法とは少し異なりますが、すべてのコマンドライン処理をargparseオブジェクト内に保持します。

(この回答のためにコードを短くするために、コードを少し切り詰めました。)

import os
import argparse

# Global preparser and options.
preparser = argparse.ArgumentParser(add_help=False)
preparser.add_argument("--user", dest="user", default=os.environ.get("USER"))

# ****** NEW *******
options, _ = preparser.parse_known_args() # Ignore what we haven't defined yet
user = options.user                       # Use this to define the default of --config

parser = argparse.ArgumentParser(parents=[ preparser ], add_help=True,
                   formatter_class=argparse.ArgumentDefaultsHelpFormatter)

# Sub-command parser and options.
subparsers = parser.add_subparsers()

command = subparsers.add_parser("command")

# ****** MODIFIED *******
command.add_argument("--config", dest="config", default="~%s/config" % (user,))

options = parser.parse_args()
于 2012-08-28T21:20:31.553 に答える
0

これは、実行時にヘルプ ラインを直接変更するソリューションです。os.environまた、他のグローバルも変更できますが、簡単にします。add_argument('--config'...)重要なのは、によって作成されたアクションを変数に 割り当てることです。helpその変数の単なる属性です。あなたはそれを自由に変更できます。

class FooAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        config.help = 'new user (%s)'% values
        setattr(namespace, self.dest, values)

parser = argparse.ArgumentParser()
parser.add_argument('--user',action=FooAction)
sub = parser.add_subparsers()
cmd = sub.add_parser('cmd')
config = cmd.add_argument('--config',help='initial help')
config.help = 'default help' # alt way of setting 'help'
# print config  # to see other attributes of the config action
args = parser.parse_args()
print args

cmd -h取得するだけで呼び出されますdefault help

$ python stack12167228.py cmd -h
usage: stack12167228.py cmd [-h] [--config CONFIG]

optional arguments:
  -h, --help       show this help message and exit
  --config CONFIG  default help

で呼び出すと--user xxx cmd -h、ヘルプがカスタマイズされます

$ python stack12167228.py --user xxx cmd -h
usage: stack12167228.py cmd [-h] [--config CONFIG]

optional arguments:
  -h, --help       show this help message and exit
  --config CONFIG  new user (xxx)
于 2013-10-10T03:18:43.410 に答える