Ich habe argparse
für ein Python-Programm verwendet -process
, das -upload
oder beides kann:
parser = argparse.ArgumentParser(description='Log archiver arguments.')
parser.add_argument('-process', action='store_true')
parser.add_argument('-upload', action='store_true')
args = parser.parse_args()
Das Programm ist ohne mindestens einen Parameter bedeutungslos. Wie kann ich konfigurieren argparse
, dass mindestens ein Parameter ausgewählt wird?
AKTUALISIEREN:
Folgen Sie den Kommentaren: Wie kann ein Programm mit mindestens einer Option pythonisch parametrisiert werden?
-x
ist universell eine Flagge und optional. Schneiden Sie die,-
wenn es erforderlich ist.process
das Standardverhalten festlegen (ohne dass Optionen angegeben werden müssen) und dem Benutzer erlauben, dies zu ändern,upload
wenn diese Option festgelegt ist? Normalerweise sollten Optionen optional sein, daher der Name. Erforderliche Optionen sollten vermieden werden (dies ist auch in denargparse
Dokumenten enthalten).Antworten:
quelle
argparse
Dies ist wahrscheinlich der einzige Weg, wenn hierfür keine Option integriert ist.quelle
vars()
, die auch nützlich ist, um sorgfältig benannte Optionen mit ** an einen Konstruktor zu übergeben.vars
. Ich habe es einfach getan.__dict__
und fühlte mich vorher dumm.Wenn nicht der Teil 'oder beides' (ich habe dies anfangs verpasst), könnten Sie so etwas verwenden:
Wahrscheinlich wäre es jedoch besser, stattdessen Unterbefehle zu verwenden.
quelle
--process
OR zulassen--upload
, nicht XOR. Dies verhindert, dass beide Optionen gleichzeitig eingestellt werden.-x
und--xxx
in der Regel optionale Parameter sind.Ich weiß, dass dies so alt wie Schmutz ist, aber der Weg, eine Option zu verlangen, aber mehr als eine (XOR) zu verbieten, ist wie folgt:
Ausgabe:
quelle
Anforderungsüberprüfung
argparse
(ich werde diesen ignorieren)Es gibt auch einige implizite Anforderungen, wenn Sie in der Befehlszeile leben:
Beispiellösung mit
docopt
(Dateimanagelog.py
):Versuchen Sie es auszuführen:
Zeigen Sie die Hilfe:
Und benutze es:
Kurze Alternative
short.py
Es kann noch kürzere Varianten geben:
Die Verwendung sieht folgendermaßen aus:
Beachten Sie, dass anstelle von booleschen Werten für die Schlüssel "process" und "upload" Zähler vorhanden sind.
Es stellt sich heraus, dass wir die Verdoppelung dieser Wörter nicht verhindern können:
Schlussfolgerungen
Das Entwerfen einer guten Befehlszeilenschnittstelle kann manchmal eine Herausforderung sein.
Es gibt mehrere Aspekte eines befehlszeilenbasierten Programms:
argparse
bietet viel, schränkt aber mögliche Szenarien ein und kann sehr komplex werden.Die
docopt
Dinge werden viel kürzer, während die Lesbarkeit erhalten bleibt und ein hohes Maß an Flexibilität geboten wird. Wenn Sie es schaffen, analysierte Argumente aus dem Wörterbuch abzurufen und einige Konvertierungen (in Ganzzahlen, Öffnen von Dateien ...) manuell (oder in einer anderen aufgerufenen Bibliothekschema
)docopt
durchzuführen, ist die Analyse der Befehlszeile möglicherweise gut geeignet.quelle
Wenn Sie ein Python-Programm benötigen, das mit mindestens einem Parameter ausgeführt werden soll, fügen Sie ein Argument hinzu, das nicht über das Optionspräfix (- oder - standardmäßig) verfügt, und setzen Sie
nargs=+
(mindestens ein Argument erforderlich). Das Problem mit dieser Methode, das ich gefunden habe, ist, dass argparse, wenn Sie das Argument nicht angeben, einen Fehler "zu wenige Argumente" generiert und das Hilfemenü nicht druckt. Wenn Sie diese Funktionalität nicht benötigen, gehen Sie wie folgt in Code vor:Ich denke , wenn Sie ein Argument mit den Optionspräfixen hinzufügen, regiert nargs den gesamten Argumentparser und nicht nur die Option. (Was ich meine ist, wenn Sie eine
--option
Fahne mitnargs="+"
, dann--option
Flagge erwartet mindestens ein Argument. Wenn Sieoption
mitnargs="+"
, es erwartet mindestens ein Argument insgesamt.)quelle
choices=['process','upload']
diesem Argument hinzufügen .Für http://bugs.python.org/issue11588 untersuche ich Möglichkeiten, das
mutually_exclusive_group
Konzept zu verallgemeinern, um solche Fälle zu behandeln.Mit dieser Entwicklung
argparse.py
, https://github.com/hpaulj/argparse_issues/blob/nested/argparse.py kann ich schreiben:welches Folgendes erzeugt
help
:Dies akzeptiert Eingaben wie '-u', '-up', '--proc --up' usw.
Am Ende wird ein Test ausgeführt, der https://stackoverflow.com/a/6723066/901925 ähnelt , obwohl die Fehlermeldung klarer sein muss:
Ich wundere mich:
Sind die Parameter
kind='any', required=True
klar genug (akzeptieren Sie einen der Gruppen; mindestens einer ist erforderlich)?Ist die Verwendung
(-p | -u)
klar? Eine erforderliche gegenseitig ausschließende Gruppe erzeugt dasselbe. Gibt es eine alternative Notation?Ist die Verwendung einer solchen Gruppe intuitiver als ein
phihag's
einfacher Test?quelle
add_usage_group
auf dieser Seite keine Erwähnung finden : docs.python.org/2/library/argparse.html ; Geben Sie bitte einen Link zur Dokumentation an.Der beste Weg, dies zu tun, ist die Verwendung des in Python eingebauten Moduls add_mutually_exclusive_group .
Wenn Sie möchten, dass nur ein Argument über die Befehlszeile ausgewählt wird, verwenden Sie einfach required = True als Argument für die Gruppe
quelle
Vielleicht Unterparser verwenden?
Jetzt
--help
zeigt:Sie können diesen Unterparsern auch zusätzliche Optionen hinzufügen. Anstatt dies zu verwenden, können
dest='subparser_name'
Sie auch Funktionen binden, die bei einem bestimmten Unterbefehl direkt aufgerufen werden sollen (siehe Dokumente).quelle
Dies erfüllt den Zweck und dies wird auch in der automatisch generierten argparse-
--help
Ausgabe berücksichtigt, was imho das ist, was die meisten vernünftigen Programmierer wollen (funktioniert auch mit optionalen Argumenten):Offizielle Dokumente dazu: https://docs.python.org/3/library/argparse.html#choices
quelle
Verwenden Sie append_const für eine Liste von Aktionen und überprüfen Sie, ob die Liste ausgefüllt ist:
Sie können die Methoden sogar direkt in den Konstanten angeben.
quelle