eine benutzerdefinierte Aktion verwenden:
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())
Dies kann sogar in ein wenig leichter gemacht werden Art und Weise zu pflegen, wenn Sie mit unter Berufung auf einige undokumentierte Verhalten von argparse OK sind:
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())
In In diesem Beispiel erhalten wir den Standard für foo
und sein Ziel aus dem Aktionsobjekt, das von add_argument
zurückgegeben wird (der Rückgabewert von add_argument ist nirgendwo dokumentiert, das ich finden kann). Dies ist immer noch etwas fragil (Wenn Sie beispielsweise ein type=
Schlüsselwort für das Argument --foo
angeben möchten).
Schließlich können Sie überprüfen sys.argv
vor dem Parsen.
import sys
if ("--parameter2" in sys.argv) and ("--parameter1" not in sys.argv):
parser.error("parameter1 must be given if parameter2 is given")
Dies wird ein wenig komplizierter, wenn --parameter1
auch durch --p1
ausgelöst werden könnte, aber Sie bekommen die Idee. Dann können Sie
verwenden
if (set(sys.argv).intersection(('--p2',...)) and
not set(sys.argv).intersection(('--p1',...)))
Der Vorteil hier ist, dass es keine bestimmte Reihenfolge erfordert. (--p2
muss nicht --p1
auf der Kommandozeile folgen). Und wie zuvor können Sie die Liste der Befehlszeichenfolgen abrufen, die Ihre bestimmte Aktion über das option_strings
-Attribut auslösen, das von parser.add_argument(...)
zurückgegeben wird. z.B.
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))
Was möchten Sie tun, wenn 'myScript.py --parameter2 Wert2 --parameter1 Wert1 passieren? Dies ist ein sehr schwieriger Fall, wenn Sie möchten, dass er besteht. – mgilson
http://bugs.python.org/issue11588 ist eine Fehleranforderung für eine Funktion 'wechselseitig_inklusive_Gruppe'. Das würde in diesem Fall nicht ganz funktionieren, da '-Parameter1' ohne' -Parameter2' auftreten kann. Tragen Sie zu diesem Problem bei, wenn Sie Ideen haben, wie diese oder ähnliche Einschränkungen implementiert werden könnten. – hpaulj