0

コマンドラインから明示的に渡されたオプションを知りたいです。

で次の argparse セットアップを検討してくださいtest.py

parser.add_argument("--foo", default=True, action="store_true")
parser.add_argument("--bar", default=False, action="store_true")

を実行すると、名前空間で が取得されます./test.py --foo --bar。 この場合、コマンドラインから明示的に渡されました。foo=Truebar=True
--foo--bar

を実行すると、名前空間で , が取得され ます./test.py --barfoo=Truebar=True

したがって、デフォルトの機能を犠牲にすることなく、コマンドラインを介して実行中に実際に渡された引数を見つける必要があります (2 番目のケースでは : )。--bar

1 つの方法は で検索することですargvが、効率的ではなく、見栄えもよくありません。これを可能にするargparse APIまたはその他のより良いアプローチがあるかどうか知りたいですか?

4

4 に答える 4

0

「store_true」アクションでは、組み込みのデフォルトは「False」です

parser.add_argument('--foo',action='store_true')

入力が生成されない

Namespace(foo=False)

「--foo」が生成する間

Namespace(foo=True)

parser.add_argument('--foo',action='store_true', default=True)

いつもfoo=Trueです。その議論は無用です。「store_true」または「store_false」を使用する場合は、独自のデフォルトを設定しないでください。

ユーザーがあなたに a を与えたかどうかを知りたい場合は--foo、最初のフォームを使用して、名前空間の値が true かどうかを確認します。後のコードで、ユーザーがあなたに与えたものfooTrue関係なくする必要がある場合は、 を使用した後に明示的に設定してくださいargparse

于 2013-09-26T22:43:03.093 に答える
0

ここでの回答とコメントでは、デフォルトを設定せず、コード内で自分でデフォルトを処理することをお勧めします。ただし、add_argument呼び出しは完全に私の制御下にあるわけではないため、これは実際にはオプションではありませんでした.

最初に、 のオプションの存在を確認しましたsys.argv。このアプローチは、非効率的でバグが発生しやすく、スケーラブルではないことがすぐに判明しました。

最後に、私はこれでうまくいったようです:

class _Reflection(object):
    def __init__(self, source, reflection, name=None):
        self.source = source
        self.reflection = reflection
        self.name = name

    def __getattr__(self, attribute):
        self.attribute = attribute
        return _Reflection(self.source.__getattribute__(attribute), self.reflection.__getattribute__(attribute), name=attribute)

    def __call__(self, *args, **kwargs):
        source_output = self.source(*args, **kwargs)

        if self.name == 'add_argument':
            # if the method being called is 'add_argument',
            # over-ride the 'default' argument's value to 'None' in our secondary argparser.
            kwargs['default'] = None

        reflection_output = self.reflection(*args, **kwargs)
        return _Reflection(source_output, reflection_output)

class ReflectionArgumentParser(object):
    def create(self, *args, **kwargs):
        self.parser = argparse.ArgumentParser(*args, **kwargs)
        self._mirror = argparse.ArgumentParser(*args, **kwargs)
        return _Reflection(self.parser, self._mirror)

    def parse_args(self, *args, **kwargs):
        return self.parser.parse_args(*args, **kwargs)

    def filter_defaults(self, *args, **kwargs):
        return self._mirror.parse_args(*args, **kwargs)

mirrorParser = ReflectionArgumentParser()
parser = mirrorParser.create()

parser.add_argument('-f', '--foo', default=False, action="store_true")
parser.add_argument('-b', '--baz', default=0, action="store_const", const=10)
parser.add_argument('bar', nargs='*', default='bar')

print mirrorParser.parse_args([])
# Outputs: Namespace(bar='bar', baz=0, foo=False)

print mirrorParser.filter_defaults([])
# Outputs: Namespace(bar=[], baz=None, foo=None)

print mirrorParser.filter_defaults('--foo -b lorem ipsum'.split())
# Outputs: Namespace(bar=['lorem', 'ipsum'], baz=10, foo=True)

この実装を引数グループとサブパーサーで試しました。
これはメソッドを扱いませんset_defaultsが、必要な追加は簡単です。

于 2014-01-26T17:10:35.093 に答える