2016-08-27 11 views
3

私のプログラムは、相互排他的な位置指定の引数であるを引数のグループとして表示するようにします。
現在、私は唯一これは私が現在持っているものであるPython:相互排他的な位置指定の引数

...どちらか一方ではなく、両方を実現できます。以下を与える

def parse_arguments(): 
    arg_parser = argparse.ArgumentParser(description = 'Project Builder') 

    query_parser = arg_parser.add_argument_group('query', "Query current state") 
    build_parser = arg_parser.add_argument_group('build', "Build project") 

    # query arguments 
    query_parser.add_argument('-s', '--servers', 
       action = 'store_true', 
       required = False, 
       help  = 'Display available servers') 

    query_parser.add_argument('-u', '--users', 
       action = 'store_true', 
       required = False, 
       help  = 'Display current users') 



    # build arguments 
    build_parser.add_argument('-f', '--force', 
       action = 'store', 
       required = False, 
       metavar = 'SERVER_NAME', 
       help  = 'Force build on SERVER_NAME') 

    build_parser.add_argument('-c', '--clean', 
       action = 'store_true', 
       required = False, 
       help  = 'Clean repo before build') 

    build_parser.add_argument('-v', '--verbosity', 
       action = 'store_true', 
       required = False, 
       help  = 'Print stderr to console') 

    build_parser.add_argument('-p', '--project', 
       action = 'store', 
       required = True, 
       metavar = 'project_A|project_B|project_C', 
       type  = project_name, 
       help  = 'Project to build (required)') 

    return vars(arg_parser.parse_args()) 


args = parse_arguments() 

usage: test.py [-h] [-s] [-u] [-f SERVER_NAME] [-c] [-v] -p 
       project_A|project_B|project_C 

Project Builder 

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

query: 
    Query current state 

    -s, --servers   Display available servers 
    -u, --users   Display current users 

build: 
    Build project 

    -f SERVER_NAME, --force SERVER_NAME 
         Force build on SERVER_NAME 
    -c, --clean   Clean repo before build 
    -v, --verbosity  Print stderr to console 
    -p project_A|project_B|project_C, --project project_A|project_B|project_C 
         Project to build (required) 

しかし、どのような私が本当に欲しいのは、querybuildが互いに排他的な2つの位置引数になることです。

次のように私はsubparsersを使用してみました:

def parse_arguments(): 
    arg_parser = argparse.ArgumentParser(description = 'Project Builder') 
    command_parser = arg_parser.add_subparsers(help = "Command") 

    query_parser = command_parser.add_parser('query', help = "Query current state") 
    build_parser = command_parser.add_parser('build', help = "Build project") 

    # query arguments 
    query_parser.add_argument('-s', '--servers', 
       action = 'store_true', 
       required = False, 
       help  = 'Display available servers') 

    query_parser.add_argument('-u', '--users', 
       action = 'store_true', 
       required = False, 
       help  = 'Display current users') 



    # build arguments 
    build_parser.add_argument('-f', '--force', 
       action = 'store', 
       required = False, 
       metavar = 'SERVER_NAME', 
       help  = 'Force build on SERVER_NAME') 

    build_parser.add_argument('-c', '--clean', 
       action = 'store_true', 
       required = False, 
       help  = 'Clean repo before build') 

    build_parser.add_argument('-v', '--verbosity', 
       action = 'store_true', 
       required = False, 
       help  = 'Print stderr to console') 

    build_parser.add_argument('-p', '--project', 
       action = 'store', 
       required = True, 
       metavar = 'project_A|project_B|project_C', 
       type  = project_name, 
       help  = 'Project to build (required)') 

    return vars(arg_parser.parse_args()) 

をしかし、これは次のように生成します。

私がしたいことは、すなわち、上記2回の試行を組み合わせたものです
usage: test.py [-h] {query,build} ... 

Project Builder 

positional arguments: 
    {query,build} Command 
    query  Query current state 
    build  Build project 

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

usage: test.py [-h] {query,build} ... 

Project Builder 

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

query: 
    Query current state 

    -s, --servers   Display available servers 
    -u, --users   Display current users 

build: 
    Build project 

    -f SERVER_NAME, --force SERVER_NAME 
         Force build on SERVER_NAME 
    -c, --clean   Clean repo before build 
    -v, --verbosity  Print stderr to console 
    -p project_A|project_B|project_C, --project project_A|project_B|project_C 
         Project to build (required) 

ここで、querybuildは互いに排他的です。
私はArgumentParser.add_mutually_exclusive_group(required=False)メソッドについて知っていますが、それを使用すると、1)引数はオプションである必要があります.2)usageのフォーマットは好きではないためです。最初のシナリオでは

答えて

0

、あなたは-p選択肢に

build_parser.add_argument('-p', '--project', 
      action = 'store', # default 
      required = True, 
      choices = ['project_A','project_B','project_C'], 
      # type  = project_name, # doesn't make sense 
      help  = 'Project to build (required)') 

や位置

build_parser.add_argument('project', 
      choices = ['project_A','project_B','project_C'], 
      help  = 'Project to build') 

typeとしてを与えることができる機能、あなたが望む何か、などの文字列として変換さ1でなければなりませんint('1')float('12.343')

サブパーザの使用は似ています。メインパーサーには、subparser引数は選択肢のある位置にすぎません。しかし、実行されるアクションは、残りの引数の解析をサブパーザーに引き渡すことです。

二つの相互に排他的positionalsは、それはあなたがfooまたはbarに文字列を割り当てるか、単に位置に基づいて、言うことができない

`[foo | bar]` 

論理的意味がありません。しかし、値に基づいて値を割り当てることや、値を選択肢のセットに制限することに興味があります。

慎重に見ることなく、サブパーザのコードが正しいように見えるので、必要に応じて入力を解析する必要があります。あなたはそれをテストしましたか?

サブパーザーのヘルプ表示は、それほど柔軟ではありませんが、再作業にはかなりの労力がかかります(これについては別に質問があります)。現在の設定では、メインのパーサーと各サブパパーのヘルプ表示を別々にすることです。包括的なヘルプ表示は組み込まれていません。

+0

'project_name'は関数名(プロジェクト名が正しいことを確認するベリファイア)であるため、' type = project_name'は意味があります。 "2つの相互に排他的な位置引数"は単語の最良の選択ではないと思います... 私が望むのは、ユーザーがサブコマンドを提供しなければならない 'git'のような動作です("相互排他的な位置引数 " 'status'、' show'、 'branch'など)を指定します。 –

+0

'project_name'があなた自身の関数であるなら、おそらく' choices'テストに似た何かをします。私は、このパラメータを誤って使用して、オブジェクトクラスを指定していると思うポスターを投稿するのに慣れています。私は 'subparsers'は他のシステムではサブコマンドとして動作するはずですが、詳細は異なっていると確信しています。 – hpaulj

関連する問題