Was wäre der beste Weg, um zu überprüfen, ob eine Variable für das Skript übergeben wurde:
try:
sys.argv[1]
except NameError:
startingpoint = 'blah'
else:
startingpoint = sys.argv[1]
Was wäre der beste Weg, um zu überprüfen, ob eine Variable für das Skript übergeben wurde:
try:
sys.argv[1]
except NameError:
startingpoint = 'blah'
else:
startingpoint = sys.argv[1]
Antworten:
Am Ende ist der Unterschied zwischen try, exceptund Testen len(sys.argv)nicht allzu bedeutend. Sie sind beide ein bisschen hackisch im Vergleich zu argparse.
Dies fällt mir jedoch ein - als eine Art Low-Budget-Streit:
arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))
Sie können es sogar verwenden, um ein namedtuplemit Werten zu generieren , die standardmäßig verwendet werden None- alles in vier Zeilen!
Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))
Falls Sie nicht vertraut sind namedtuple, handelt es sich nur um ein Tupel, das sich wie ein Objekt verhält und es Ihnen ermöglicht, auf seine Werte mithilfe der tup.attributeSyntax anstelle der tup[0]Syntax zuzugreifen .
In der ersten Zeile wird also ein neuer namedtupleTyp mit Werten für jeden der Werte in erstellt arg_names. In der zweiten Zeile werden die Werte aus dem argsWörterbuch übergeben, getum einen Standardwert zurückzugeben, wenn dem angegebenen Argumentnamen kein Wörterwert im Wörterbuch zugeordnet ist.
Überprüfen Sie die Länge von sys.argv:
if len(sys.argv) > 1:
blah = sys.argv[1]
else:
blah = 'blah'
Einige Leute bevorzugen den von Ihnen vorgeschlagenen ausnahmebasierten Ansatz (z. B. try: blah = sys.argv[1]; except IndexError: blah = 'blah'), aber ich mag ihn nicht so sehr, weil er nicht annähernd so gut „skaliert“ (z. B. wenn Sie zwei oder drei Argumente akzeptieren möchten). und es kann möglicherweise Fehler verbergen (z. B. wenn Sie einen verwendet blah = foo(sys.argv[1]), aber foo(...)ausgelöst IndexErrorhaben, IndexErrorder ignoriert wird).
try, except. Warten fooSie einfach auf Ihr Argument bis zur elseKlausel.
argparse.
argparse.pyin all meinen Kommandozeilenprojekten.
tryKlausel ein. Da es also nicht schwieriger (und meiner Meinung nach etwas hübscher) ist, ziehe ich es vor, nur die Länge zu überprüfen (außerdem vermeiden Sie es, Leute zu haben schreien Sie an, weil Sie Ausnahmen für die Flusskontrolle verwendet haben).
tryentschuldigend, muss ich zugeben. Ich habe nur das Gefühl, dass es manchmal meine Absicht klarer ausdrückt als eine ifAussage.
Eine andere Möglichkeit, die ich noch nicht aufgelistet habe, besteht darin, Ihren Sentinel-Wert im Voraus festzulegen. Diese Methode nutzt die verzögerte Auswertung von Python, bei der Sie nicht immer eine elseAnweisung angeben müssen. Beispiel:
startingpoint = 'blah'
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
Oder wenn Sie die Syntax CRAZY verwenden, können Sie den ternären Operator von Python verwenden :
startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'
Ich benutze das - es scheitert nie:
startingpoint = 'blah'
if sys.argv[1:]:
startingpoint = sys.argv[1]
startingpointVariable aus dem Beispiel entfernen , aber die Frage ist, eine Fallback-Variable zuzuweisen , also habe ich das gleiche gemacht.
sys.argv[1:]:. Dies funktioniert mit Positionsargumenten, die Anzahl jedoch nicht.
Es ist eine gewöhnliche Python-Liste. Die Ausnahme, die Sie dafür abfangen würden, ist IndexError, aber Sie sollten stattdessen nur die Länge überprüfen.
if len(sys.argv) >= 2:
startingpoint = sys.argv[1]
else:
startingpoint = 'blah'
Eine Lösung, die mit der in die Karte integrierten Funktion funktioniert!
arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}
Dann müssen Sie nur noch Ihre Parameter wie folgt aufrufen:
if args['operation'] == "division":
if not args['parameter']:
...
if args['parameter'] == "euclidian":
...
Sie können einfach den Wert von argv [1] an argv anhängen und dann prüfen, ob argv [1] nicht der von Ihnen eingegebenen Zeichenfolge entspricht. Beispiel:
from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
print(argv[1])
Ziemlich nah an dem, was der Urheber versucht hat. Hier ist eine Funktion, die ich benutze:
def get_arg(index):
try:
sys.argv[index]
except IndexError:
return ''
else:
return sys.argv[index]
Eine Verwendung wäre also ungefähr so:
if __name__ == "__main__":
banner(get_arg(1),get_arg(2))