カスタム アクションを使用します。
import argparse
foo_default=None
class BarAction(argparse.Action):
def __call__(self,parser,namespace,values,option_string=None):
didfoo=getattr(namespace,'foo',foo_default)
if(didfoo == foo_default):
parser.error( "foo before bar!")
else:
setattr(namespace,self.dest,values)
parser=argparse.ArgumentParser()
parser.add_argument('--foo',default=foo_default)
parser.add_argument('--bar',action=BarAction,help="Only use this if --foo is set")
#testing.
print parser.parse_args('--foo baz'.split())
print parser.parse_args('--foo baz --bar cat'.split())
print parser.parse_args('--bar dog'.split())
これは、argparse の文書化されていない動作に依存しても問題ない場合は、維持するのが少し簡単な方法で行うこともできます。
import argparse
parser=argparse.ArgumentParser()
first_action=parser.add_argument('--foo',dest='cat',default=None)
class BarAction(argparse.Action):
def __call__(self,parser,namespace,values,option_string=None):
didfoo=getattr(namespace,first_action.dest,first_action.default)
if(didfoo == first_action.default):
parser.error( "foo before bar!")
else:
setattr(namespace,self.dest,values)
parser.add_argument('--bar',action=BarAction,
help="Only use this if --foo is set")
#testing.
print parser.parse_args('--foo baz'.split())
print parser.parse_args('--foo baz --bar cat'.split())
print parser.parse_args('--bar dog'.split())
この例では、デフォルトの for を取得しfoo
、それはによって返されるアクション オブジェクトから宛先になりますadd_argument
(add_argument の戻り値は、私が見つけることができるどこにも文書化されていません)。これはまだ少し壊れやすいです(たとえば、引数にtype=
キーワードを指定したい場合)。--foo
sys.argv
最後に、解析する前に 確認できます。
import sys
if ("--parameter2" in sys.argv) and ("--parameter1" not in sys.argv):
parser.error("parameter1 must be given if parameter2 is given")
--parameter1
によってもトリガーされる場合、これはもう少しトリッキーになり--p1
ますが、アイデアはわかります。次に、使用できます
if (set(sys.argv).intersection(('--p2',...)) and
not set(sys.argv).intersection(('--p1',...)))
ここでの利点は、特定の順序を必要としないことです。(コマンドライン--p2
でフォローする必要はありません)。--p1
そして、前と同様に、option_strings
によって返される属性を介して特定のアクションをトリガーするコマンド文字列のリストを取得できますparser.add_argument(...)
。例えば
import argparse
import sys
parser=argparse.ArgumentParser()
action1=parser.add_argument('--foo')
action2=parser.add_argument('--bar',
help="Only use this if --foo is set")
argv=set(sys.argv)
if (( argv & set(action2.option_strings) ) and
not ( argv & set(action1.option_strings) )):
#^ set intersection
parser.error(' or '.join(action1.option_strings)+
' must be given with '+
' or '.join(action2.option_strings))