ここでの回答とコメントでは、デフォルトを設定せず、コード内で自分でデフォルトを処理することをお勧めします。ただし、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
が、必要な追加は簡単です。