5

argparsefilename cmd lineパラメータのファイル名拡張子を検証するために使用できますか?

たとえば、Pythonスクリプトがある場合は、cmd行から実行します。

$ script.py file.csv
$ script.py file.tab
$ script.py file.txt

argparseで最初の2つのfilenamecmd行オプションを受け入れたいが、3番目を拒否したい

私はあなたがこのようなことをすることができることを知っています:

parser = argparse.ArgumentParser()
parser.add_argument("fn", choices=["csv","tab"])
args = parser.parse_args()

cmd行オプションに2つの有効な選択肢を指定する

私が欲しいのはこれです:

parser.add_argument("fn", choices=["*.csv","*.tab"])

cmdlineオプションに2つの有効なファイル拡張子を指定します。残念ながら、これは機能しません-これを使用してこれを達成する方法はありargparseますか?

4

3 に答える 3

9

確かに - として適切な関数を指定する必要があるだけですtype

import argparse
import os.path

parser = argparse.ArgumentParser()

def file_choices(choices,fname):
    ext = os.path.splitext(fname)[1][1:]
    if ext not in choices:
       parser.error("file doesn't end with one of {}".format(choices))
    return fname

parser.add_argument('fn',type=lambda s:file_choices(("csv","tab"),s))

parser.parse_args()

デモ:

temp $ python test.py test.csv
temp $ python test.py test.foo
usage: test.py [-h] fn
test.py: error: file doesn't end with one of ('csv', 'tab')

これは、おそらくよりクリーンで一般的な方法です。

import argparse
import os.path

def CheckExt(choices):
    class Act(argparse.Action):
        def __call__(self,parser,namespace,fname,option_string=None):
            ext = os.path.splitext(fname)[1][1:]
            if ext not in choices:
                option_string = '({})'.format(option_string) if option_string else ''
                parser.error("file doesn't end with one of {}{}".format(choices,option_string))
            else:
                setattr(namespace,self.dest,fname)

    return Act

parser = argparse.ArgumentParser()
parser.add_argument('fn',action=CheckExt({'csv','txt'}))

print parser.parse_args()

ここでの欠点は、いくつかの点でコードが少し複雑になっていることです。つまり、実際に引数をフォーマットするときに、インターフェイスが少しきれいになるということです。

于 2013-03-04T14:34:20.930 に答える
7

名前を文字列として受け取るカスタム関数を定義します-比較のために拡張子を分割し、問題がない場合は文字列を返します。それ以外の場合は、argparseが予期する例外を発生させます。

def valid_file(param):
    base, ext = os.path.splitext(param)
    if ext.lower() not in ('.csv', '.tab'):
        raise argparse.ArgumentTypeError('File must have a csv or tab extension')
    return param

次に、次のような関数を使用します。

parser = argparse.ArgumentParser()
parser.add_argument('filename', type=valid_file)
于 2013-03-04T14:36:58.147 に答える
-3

いいえ。choices 引数、または「in」演算子をサポートする任意のものにコンテナー オブジェクトを提供できます。pydocsで詳細を読むことができます

ただし、いつでも自分で確認して、ユーザーにフィードバックを提供できます。

于 2013-03-04T14:33:44.250 に答える