2016-07-06 3 views
1

ごとに異なる必須/使用可能なパラメータ私は、次の構造を持つ引数パーサを作成するために探しています:argparse - アクション

options [ 'backup', 'consistency_check', 'backup_and_consistency_check'] 

--database [ required ] 
--action [ required choice from list options ] 
    --where_to_backup_to [ only required if --action is 'backup' ] 
    --what_file_to_consistency_check [ only required if --action is 'consistency_check'] 
--clean [ optional ] 
    --force [ optional if --clean is also in arguments ] 

どのようにしていた選択に応じて、ArgumentParserモジュールを使用してオプションの引数を実装することができます別のコマンドライン引数として作成されます。私はArgParse作るために探してい

は、例えば、コマンドライン引数が、これは私がこれまでに得ている(私はそれが非常に少ないことを知っているものです

--d database_name --a backup --what_file_to_consistency_check /var/tmp/file.bak 

ある場合に失敗しますが、私はしたくありません私は最初から右のそれをもらっていない場合、私は、動的オプションパーサとの位置パラメータのアクションを行うことだと思い

actions = ['backup', 'consistency_check', 'backup_and_consistency_check'] 

def create_parser(): 
    parser = ArgumentParser(description='Parser for Backup/Consistency Check') 

    parser.add_argument('--database', '-d', dest='db', help='Database name', choices=get_active_database_list()) 

    parser.add_argument('--action', '-a', dest='action', help='Action option', choices=actions) 
    # --where_to_backup_to [ only if action = backup ] 
    # --what_file_to_consistency_check [ only if action = cc ] 
    parser.add_argument('--clean', '-c', dest='clean', help='Clean') 
    # --force [ only available if --clean is also in arguments ] 

    return parser 
+1

各アクションに独自のサブパーザを付けます。ところで、従来は、行動を位置的な議論にしていました。 –

+0

例を挙げることはできますか?それは実際のコードでなければならないことさえありません - ただの説明ですか?パーサ全体ではなく、特定の引数にサブパーザを追加できますか? – AK47

+0

アクションに対する条件付きとは、* for *のサブパーサーであるため、ドキュメントの例がすべて適用されます。 –

答えて

1

サブパーザーが現時点では複雑すぎると思われる場合、私はあなたがまだ役に立つパーザを得ることができると思います:

def create_parser(): 
    parser = ArgumentParser(description='Parser for Backup/Consistency Check') 

    parser.add_argument('--database', '-d', dest='db', help='Database name', choices=get_active_database_list()) 

    parser.add_argument('--action', '-a', help='Action option', choices=actions) 
    parser.add_argument('target', help='target for backup or check') 
    parser.add_argument('--clean', '-c', help='Clean') # default dest is 'clean' 
    parser.add_argument('--force', help='force clean') 
    return parser 

databaseが必要な場合は、required=Trueパラメータを追加します。またはそれをポジションにします。それ以外の場合は、ユーザーがそれを提供していない場合に行うことを検討してください。私。 if​​?あなたが使用できるデフォルトのデータベースはありますか?

すべてのアクションの選択肢は、ファイルまたはdir引数(バックアップまたはチェックの対象)を必要とするようです。ユーザーが ' - 場所_to_backup_to'または '--what_file_to_consistency_check'と呼ぶかどうかは重要ですか?ここでポジションを使うことで、何らかの名前を付ける必要がありますが、それは「アクション」に従って解釈することです。

forceはちょうどcleanのより強力なバージョンです。 --forceを指定しても--cleanを指定しないと、ユーザーは何を望んでいると思いますか?ここで私は両方を受け入れ、あなたのコードが最も理にかなったものを選択させるようにします。

私の哲学は、パーサーの主な目標は、ユーザーが望むものを理解することです。エラーチェックは、あいまいな入力を防ぐ場合に最も便利です。しかし、それは気まずいてはいけません。単純なパーサ設計は、通常、複雑すぎる設計よりも優れています。

1

)subparsersと完全に間違った方向に行くことは良いオプションです:

if __name__ == "__main__": 

    action = sys.argv[1] 

    parser = create_parser(action) 
    args = parser.parse_args() 
+1

argparseにはサブコマンドのサポートが組み込まれています。 'すべての可能性をカバーしています。また、あなたの引数の前に*オプションを持つことができます。 –

+0

こんにちは、返信ありがとうございます。私は不必要な条件を使用することを避けようとしています。オプションにも同様の機能が追加されているので、引数などから変数を取り出すことを避けようとしています - コードを新しい--cleanオプションで更新しました。チャールズが言ったことを踏まえて、ArgParseは魔法を実行するのに十分なインテリジェントなので、私はそれを最大限の可能性に利用したいと思っています:) – AK47

1

これを行うための従来の方法は、より次のようになります。

def create_parser(): 
    parser = ArgumentParser(description='Parser for Backup/Consistency Check') 

    parser.add_argument('--database', '-d', dest='db', help='Database name', choices=get_active_database_list()) 
    parser.add_argument('--timeout', '-t', dest='timeout', help='Timeout limit (in minutes)') 

    subparsers = parser.add_subparsers() 

    parser_backup = subparsers.add_parser('backup', help='Run a backup') 
    parser_backup.set_defaults(action='backup') # or even pass the backup function itself, vs a string 
    parser_backup.add_argument('dest', help='Where to backup to') # where to backup to 

    parser_check = subparsers.add_parser('consistency_check', help='Run a consistency check') 
    parser_check.set_defaults(action='consistency_check') 
    parser_check.add_argument('source', help='What file to check for consistency') 

    return parser 

...使用になど:

# here, action='backup' and dest='/path/to/dest' 
yourtool -d db -t 15 backup /path/to/dest 

...か...

# here, action='consistency_check' and source='/path/to/content/to/check' 
yourtool -d db -t 15 consistency_check /path/to/content/to/check 
+0

ありがとう、これは実際にものアップ。サブパーザを追加することによって、これは別の引数を追加するのと同じですが、この引数にはオプションの引数もあります。私は、サブパーザを追加し、サブパーザへの引数としてバックアップを追加すると思って混乱していました。しかし、バックアップはサブパーザです! – AK47

+0

'add_subparsers(dest = 'action')'の場合、(関数値を設定しない限り) 'set_defaults'文は必要ありません。 – hpaulj