2016-09-28 11 views
6

Ich erstelle ein Python-Programm mit der argparse module und ich möchte dem Programm erlauben, entweder ein Argument oder 2 Argumente zu nehmen.Argumente mit variabler Länge

Was meine ich? Nun, ich erstelle ein Programm zum Herunterladen/Dekodieren von MMS-Nachrichten und ich möchte, dass der Benutzer entweder eine Telefonnummer und eine MMS-Transaktions-ID zum Herunterladen der Daten oder zum Bereitstellen einer Datei von bereits heruntergeladenen MMS-Daten aus ihrem System bereitstellen kann.

Was ich will, ist so etwas, wo man entweder in zwei Argumente eingeben oder 1 Argument:

./mms.py (phone mmsid | file) 

HINWEIS: phone würde eine Telefonnummer sein (wie 15555555555), mmsid eine Zeichenkette (MMS-Transaktions-ID) und file eine Datei auf dem Computer des Benutzers

Ist dies mit argparse möglich? Ich hatte gehofft, ich könnte add_mutually_exclusive_group verwenden, aber das schien nicht zu tun, was ich will.

parser = argparse.ArgumentParser() 
group = parser.add_mutually_exclusive_group(required=True) 
group.add_argument('phone', help='Phone number') 
group.add_argument('mmsid', help='MMS-Transaction-ID to download') 
group.add_argument('file', help='MMS binary file to read') 

Das den Fehler gibt (required=True Entfernung gibt den gleichen Fehler):

ValueError: mutually exclusive arguments must be optional

Es sieht aus wie es mir will --phone statt phone verwenden: meine

parser = argparse.ArgumentParser() 
group = parser.add_mutually_exclusive_group(required=True) 
group.add_argument('--phone', help='Phone number') 
group.add_argument('--mmsid', help='MMS-Transaction-ID to download') 
group.add_argument('--file', help='MMS binary file to read') 

Beim Laufen Programm ohne Argumente sehe ich:

error: one of the arguments --phone --mmsid --file is required

Das ist näher an dem, was ich will, aber kann ich argparse do (--phone --msid) or (--file) machen?

+1

Können Sie [Unterbefehle] (https://docs.python.org/2/library/argparse.html#sub-commands) verwenden? – mgilson

+0

@mgilson: Ich habe das nicht untersucht. Gibt es eine Möglichkeit, einen "Standard" -Befehl zu machen? Wie './mms.py file.bin' anstelle von' ./mms.py decode file.bin' oder './mms.py 15555555555 abcd' statt' ./mms.py download 15555555555 abcd'. –

+0

Das ist eine gute Frage. Ich sehe nichts dokumentiert: -/... – mgilson

Antwort

4

Dies ist ein wenig über den Rahmen dessen, was argparse tun kann, da der "Typ" des ersten Arguments nicht vor der Zeit bekannt ist. Ich würde so etwas wie

tun
import argparse 

p = argparse.ArgumentParser() 
p.add_argument("file_or_phone", help="MMS File or phone number") 
p.add_argument ("mmsid", nargs="?", help="MMS-Transaction-ID") 

args = p.parse_args() 

Um zu bestimmen, ob args.file_or_phone als Dateiname bestimmt ist oder eine Telefonnummer, müssen Sie prüfen, ob oder ob nicht args.mmsid ist None.

+0

Dies scheint, mehr oder weniger, genau das, was ich zu tun versuchte. In meinem Argument 'file' hatte ich' type = argparse.FileType ('rb') '. Ich denke, ich muss 'open (args.file_or_phone, 'rb')' 'manuell aufrufen, falls nötig. –

+0

Es sieht auch so aus, als könnte ich den angezeigten Text überschreiben, um './mms.py (phone mmsid | file) anzuzeigen' (und vielleicht ein "nur mit Telefonnummer" zu mmsid hinzufügen) und dann die Argumente nach Bedarf verarbeiten. –

+1

Sie können eine benutzerdefinierte Aktion definieren, die basierend auf dem angegebenen Wert entscheidet, ob es sich um eine Telefonnummer oder einen Dateinamen handelt, und entsprechend handeln. Das Argument selbst wäre jedoch immer noch etwas wie 'p.add_argument (" file_or_phone ", action = MyCustomAction, help =" ... ")'. – chepner

Verwandte Themen