Użyj akcję niestandardową:
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())
Można to zrobić nawet w trochę łatwiej utrzymać drogę, jeśli jesteś OK z opierając się na pewnym nieudokumentowane zachowania 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())
W w tym przykładzie otrzymujemy domyślną wartość dla foo
i jest to miejsce docelowe z obiektu akcji zwróconego przez add_argument
(wartość zwracana przez add_argument nie jest udokumentowana nigdzie, co mogę znaleźć). To wciąż jest trochę delikatne (jeśli chcesz, na przykład, podać słowo kluczowe type=
do argumentu --foo
).
Na koniec można sprawdzić sys.argv
przed analizą.
import sys
if ("--parameter2" in sys.argv) and ("--parameter1" not in sys.argv):
parser.error("parameter1 must be given if parameter2 is given")
To staje się trochę bardziej skomplikowane, jeśli --parameter1
może być również wywołane przez --p1
, ale masz pomysł. Następnie można użyć tej opcji, ponieważ nie wymaga żadnej określonej kolejności. (--p2
nie musi być zgodna z --p1
w linii poleceń). I tak jak poprzednio, możesz uzyskać listę ciągów poleceń, które wyzwalają określone działanie za pomocą atrybutu option_strings
zwróconego przez parser.add_argument(...)
. na przykład
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))
Czego chcesz się zdarzyć, jeśli 'myScript.py --parameter2 value2 --parameter1 value1'? Jest to bardzo trudny przypadek, jeśli chcesz go przekazać. – mgilson
http://bugs.python.org/issue11588 to żądanie błędu dla funkcji 'mutualually_inclusive_group'. W tym przypadku nie będzie to działać, ponieważ '--parametr1' może wystąpić bez' --parametru2'. Przyczyń się do tego problemu, jeśli masz pomysły na to, w jaki sposób można wdrożyć te ograniczenia lub związane z nimi ograniczenia. – hpaulj