32

これらの myprog の呼び出しを機能させたいと思います。

$ python3 myprog.py -i infile -o outfile
$ python3 myprog.py -o outfile
$ python3 myprog.py -o
$ python3 myprog.py 

特に、アウトファイルではなくインファイルを指定することを違法にしたいと考えています。

3 番目のケースでは、outfile のデフォルト名は「out.json」と見なされます。2 番目、3 番目、4 番目のケースでは、入力ファイルのデフォルト名は「file.n.json」と想定されます。n は整数のバージョン番号です。4 番目のケースでは、出力ファイルは「file.n+1.json」になります。ここで、n+1 は入力ファイルのバージョン番号よりも 1 大きいバージョン番号です。私のコードの関連セクションは次のとおりです。

import argparse

parser = argparse.ArgumentParser(description="first python version")
parser.add_argument('-i', '--infile', nargs=1, type=argparse.FileType('r'), help='input file, in JSON format')
parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format')

args = parser.parse_args()

print("Here's what we saw on the command line: ")
print("args.infile",args.infile)
print("args.outfile",args.outfile)

if args.infile and not args.outfile:
    parser.error("dont specify an infile without specifying an outfile")
elif not args.infile:
    print("fetching infile")
else: # neither was specified on the command line
    print("fetching both infile and outfile")

問題は、実行するときです

$ python3 myprog.py -i infile.json

私が望んでいたパーサーエラーの代わりに、私は得る:

Here's what we saw on the command line: 
args.infile [<_io.TextIOWrapper name='infile.json' mode='r' encoding='UTF-8'>]
args.outfile <_io.TextIOWrapper name='out.json' mode='w' encoding='UTF-8'>
fetching both infile and outfile

...これは、コマンドラインに「-o」がなくても、あたかも存在するかのように動作したことを示唆しています。

4

2 に答える 2

22

選択した回答へのアドオンとして:

ファイルを指定せずに実行するオプションは、と組み合わせて-o使用​​できます。constnargs='?'

ドキュメントから:

オプション文字列 (-f や --foo など) および nargs='?' を指定して add_argument() が呼び出された場合。これにより、オプションの引数が作成され、その後にゼロまたは 1 つのコマンドライン引数を続けることができます。コマンド ラインを解析するときに、オプション文字列の後にコマンド ライン引数がない場合は、代わりに const の値が想定されます。例については、nargs の説明を参照してください。

例 (文字列型):

parser.add_argument('-o', '--outfile', nargs='?', const='arg_was_not_given', help='output file, in JSON format')

args = parser.parse_args()

if args.outfile is None:
    print('Option not given at all')
elif args.outfile == 'arg_was_not_given':
    print('Option given, but no command-line argument: "-o"')
elif:
    print('Option and command-line argument given: "-o <file>"')
于 2014-01-06T13:23:36.460 に答える