web-dev-qa-db-ja.com

argparseを使用したPythonの条件付きコマンドライン引数

--action=フラグをとるプログラムが欲しいのですが、有効な選択肢はdumpuploadで、uploadがデフォルトです。 dumpが選択されている場合に限り、--dump-format=オプションも追加したいと考えています。 argparseを使用してこれを表現する方法はありますか、またはすべての引数を受け入れて自分でロジックを実行する必要がありますか?.

31
Alex Gaynor

parser.error

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--action', choices=['upload', 'dump'], default='dump')
parser.add_argument('--dump-format')
args = parser.parse_args()
if args.action != 'dump' and args.dump_format:
    parser.error('--dump-format can only be set when --action=dump.')
19
Jakub

この問題に取り組む別の方法は、最初の引数として「アクション」を指定して サブコマンド (a'la git)を使用することです。

script dump --dump-format="foo"
script upload
43
codysoyland

Argparseモジュールは、独自の必要性チェックを実装せずにこれを行う方法を提供します。以下の例では、「サブパーサー」または「サブコマンド」を使用しています。 「ダンプ」用のサブパーサーと「フォーマット」用のサブパーサーを実装しました。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('file', help='The file you want to act on.')
subparsers = parser.add_subparsers(dest='subcommand')

#  subparser for dump
parser_dump = subparsers.add_parser('dump')
# add a required argument
parser_dump.add_argument(
    'format',
    choices=['csv', 'json'],
    help='Dump the file in this format.')

#  subparser for upload
parser_upload = subparsers.add_parser('upload')
# add a required argument
parser_upload.add_argument(
    'server',
    choices=['Amazon', 'imgur'],
    help='Upload the file to this service.')

args = parser.parse_args()
print args
if args.subcommand == 'dump':
    print 'I will now dump "%s" in the %s format' % (args.file, args.format)
if args.subcommand == 'upload':
    print 'I will now upload "%s" to %s' % (args.file, args.server)

コマンドラインでは次のようになります。

$ python ap.py 
usage: ap.py [-h] file {upload,dump} ...
ap.py: error: too few arguments
$ python ap.py tmp.txt 
usage: ap.py [-h] file {upload,dump} ...
ap.py: error: too few arguments
$ python ap.py tmp.txt upload
usage: ap.py file upload [-h] {Amazon,imgur}
ap.py file upload: error: too few arguments
$ python ap.py tmp.txt upload amazo
usage: ap.py file upload [-h] {Amazon,imgur}
ap.py file upload: error: argument server: invalid choice: 'amazo' (choose from 'Amazon', 'imgur')
$ python ap.py tmp.txt upload Amazon
Namespace(file='tmp.txt', server='Amazon', subcommand='upload')
I will now upload "tmp.txt" to Amazon
$ python ap.py tmp.txt upload imgur
Namespace(file='tmp.txt', server='imgur', subcommand='upload')
I will now upload "tmp.txt" to imgur
$ python ap.py tmp.txt dump
usage: ap.py file dump [-h] {csv,json}
ap.py file dump: error: too few arguments
$ python ap.py tmp.txt dump csv
Namespace(file='tmp.txt', format='csv', subcommand='dump')
I will now dump "tmp.txt" in the csv format
$ python ap.py tmp.txt dump json
Namespace(file='tmp.txt', format='json', subcommand='dump')
I will now dump "tmp.txt" in the json format

詳細: http://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser.add_subparsers

41
Niels Bom

それは、「すべてのロジックを自分で行う」と考える内容によって異なります。 argparseを使用し、サブコマンドに頼ることなく最小限の労力で次のようにダンプオプションを追加できます。

from argparse import ArgumentParser
from sys import argv

parser = ArgumentParser()
action_choices = ['upload', 'dump']
parser.add_argument('--action', choices=action_choices, default=action_choices[1])
parser.add_argument('--dump-format', required=(action_choices[1] in argv))

このように、ダンプアクションが選択されなかった場合、argparseはダンプ形式を気にしません。

0
Dmytro Bugayev