Optionale Positionsargumente argumentieren?

651

Ich habe ein Skript, das so verwendet werden soll: usage: installer.py dir [-h] [-v]

dir ist ein Positionsargument, das wie folgt definiert ist:

parser.add_argument('dir', default=os.getcwd())

Ich möchte dir, dass das optional ist: Wenn es nicht angegeben ist, sollte es einfach sein cwd.

Leider dirbekomme ich, wenn ich das Argument nicht spezifiziere Error: Too few arguments.

Waldo Bronchart
quelle

Antworten:

824

Verwenden Sie nargs='?'(oder nargs='*' wenn Sie mehr als ein Verzeichnis benötigen)

parser.add_argument('dir', nargs='?', default=os.getcwd())

erweitertes Beispiel:

>>> import os, argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-v', action='store_true')
_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('dir', nargs='?', default=os.getcwd())
_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('somedir -v'.split())
Namespace(dir='somedir', v=True)
>>> parser.parse_args('-v'.split())
Namespace(dir='/home/vinay', v=True)
>>> parser.parse_args(''.split())
Namespace(dir='/home/vinay', v=False)
>>> parser.parse_args(['somedir'])
Namespace(dir='somedir', v=False)
>>> parser.parse_args('somedir -h -v'.split())
usage: [-h] [-v] [dir]

positional arguments:
  dir

optional arguments:
  -h, --help  show this help message and exit
  -v
Vinay Sajip
quelle
14
Bedeuten das ?und *dasselbe, was sie in regulären Ausdrücken bedeuten (dh ?erfordert 0 oder 1 und *erfordert 0 oder mehr)? Wenn ja, funktioniert +das auch?
Dolan Antenucci
37
@dolan: Ja, +funktioniert auch. Weitere Informationen finden Sie unter docs.python.org/2/library/argparse.html#nargs .
Vinay Sajip
2
Gibt es eine Möglichkeit, dir zu veranlassen, in optionalen Argumenten angezeigt zu werden? oder es scheint, dass Positionsargumente ein vorangestelltes 'optionales' Qualifikationsmerkmal haben sollten. ist es möglich, es als solches zu registrieren (soweit es die Hilfe betrifft)?
Scagnetti
6
@ant Wie oben sehen Sie, dass dir optional ist (dass es in eckigen Klammern in der argparse-Ausgabe angezeigt wird, zeigt dies an).
Vinay Sajip
1
Tx! Zugriff dir von options.dir, nicht args.dir, wie ich es versucht habe!
ptim
69

Als Erweiterung zu @VinaySajip Antwort. Es gibt weitere nargserwähnenswerte .

  1. parser.add_argument('dir', nargs=1, default=os.getcwd())

N (eine ganze Zahl). N Argumente aus der Befehlszeile werden zu einer Liste zusammengefasst

  1. parser.add_argument('dir', nargs='*', default=os.getcwd())

'*'. Alle vorhandenen Befehlszeilenargumente werden in einer Liste zusammengefasst. Beachten Sie, dass es im Allgemeinen nicht viel Sinn macht, mehr als ein Positionsargument mit zu haben nargs='*', aber mehrere optionale Argumente mit nargs='*'möglich sind.

  1. parser.add_argument('dir', nargs='+', default=os.getcwd())

'+'. Genau wie bei '*' werden alle vorhandenen Befehlszeilenargumente in einer Liste zusammengefasst. Außerdem wird eine Fehlermeldung generiert, wenn nicht mindestens ein Befehlszeilenargument vorhanden war.

  1. parser.add_argument('dir', nargs=argparse.REMAINDER, default=os.getcwd())

argparse.REMAINDER. Alle verbleibenden Befehlszeilenargumente werden in einer Liste zusammengefasst. Dies ist häufig nützlich für Befehlszeilenprogramme, die an andere Befehlszeilenprogramme gesendet werden

Wenn das nargsSchlüsselwortargument nicht angegeben wird, wird die Anzahl der verwendeten Argumente von der Aktion bestimmt. Im Allgemeinen bedeutet dies, dass ein einzelnes Befehlszeilenargument verwendet und ein einzelnes Element (keine Liste) erstellt wird.

Bearbeiten (kopiert aus einem Kommentar von @Acumenus) nargs='?' Die Dokumente sagen: '?'. Ein Argument wird nach Möglichkeit über die Befehlszeile verwendet und als einzelnes Element erstellt. Wenn kein Befehlszeilenargument vorhanden ist, wird der Standardwert erzeugt.

Matas Vaitkevicius
quelle
3
Es ist jedoch zu beachten, dass nargs='?'keine Liste erstellt wird.
Acumenus
@ABB Letzte Zeile der Antwort Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced.Hoffe, das hilft ...
Matas Vaitkevicius
1
Die zitierte Zeile bezieht sich auf den Fall, dass nicht definiert nargs, sondern nargs='?'definiert wird. Die Dokumente sagen: '?'. Ein Argument wird nach Möglichkeit über die Befehlszeile verwendet und als einzelnes Element erstellt. Wenn kein Befehlszeilenargument vorhanden ist, wird der Standardwert erzeugt.
Acumenus
@ABB Bearbeiten Sie einfach die Antwort, wenn Sie das Gefühl haben, dass etwas fehlt. Vielen Dank.
Matas Vaitkevicius
Was ist der Unterschied zwischen nargs=argparse.REMAINDERund nargs='*', wie mir scheint, sind sie in ihrer Wirkung identisch (getestet in Python 2.7.10 und Python 3.6.1)?
-5

parser.add_argumenthat auch einen Schalter erforderlich . Sie können verwenden required=False. Hier ist ein Beispiel-Snippet mit Python 2.7:

parser = argparse.ArgumentParser(description='get dir')
parser.add_argument('--dir', type=str, help='dir', default=os.getcwd(), required=False)
args = parser.parse_args()
Rakhee
quelle
11
OP fragte nach Positionsparametern, nicht nach '--dir'. 'erforderlich' ist ein ungültiges Argument für Positionen. Und 'falsch' war ein Tippfehler, sie meinte 'falsch'. +1 für Neuling, -1 für Schlamperei.
SoloPilot