Argumentować opcjonalne argumenty pozycyjne?


651

Mam skrypt, którego należy używać w następujący sposób: usage: installer.py dir [-h] [-v]

dir jest argumentem pozycyjnym zdefiniowanym w następujący sposób:

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

Chcę, diraby był opcjonalny: jeśli nie jest określony, powinien po prostu być cwd.

Niestety, gdy nie podam dirargumentu, rozumiem Error: Too few arguments.

Odpowiedzi:


825

Użyj nargs='?'(lub nargs='*' jeśli będziesz potrzebować więcej niż jednego katalogu)

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

rozszerzony przykład:

>>> 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

14
Czy ?i *oznaczają to samo, co oznaczają w wyrażeniach regularnych (tj. ?Wymaga 0 lub 1 i *wymaga 0 lub więcej)? Jeśli tak, czy również +działa?
Dolan Antenucci

37
@dolan: Tak, też +działa. Szczegóły znajdują się w docs.python.org/2/library/argparse.html#nargs .
Vinay Sajip

2
czy jest jakiś sposób, żeby reż pojawił się w opcjonalnych argumentach? lub wydaje się, że argumenty pozycyjne powinny mieć poprzedzający „opcjonalny” kwalifikator. czy można zarejestrować (w zakresie pomocy) jako taką?
scagnetti

6
@ant Z powyższego widać, że katalog jest opcjonalny (wskazuje to w nawiasach kwadratowych w wynikach argparse).
Vinay Sajip

1
Tx! Uzyskaj dostęp do katalogu z options.dir, nie args.dir, tak jak próbowałem!
ptim

69

Jako rozszerzenie odpowiedzi @VinaySajip. Są dodatkowe nargswarte wspomnienia .

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

N (liczba całkowita). N argumentów z wiersza poleceń zostanie zebranych razem na liście

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

„*”. Wszystkie obecne argumenty wiersza poleceń są gromadzone na liście. Zauważ , że generalnie nie ma większego sensu mieć więcej niż jeden argument pozycyjny z nargs='*', ale nargs='*'możliwe jest wiele opcjonalnych argumentów z .

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

„+”. Podobnie jak „*” wszystkie obecne argumenty wiersza poleceń są gromadzone na liście. Ponadto zostanie wygenerowany komunikat o błędzie, jeśli nie będzie co najmniej jednego argumentu wiersza polecenia.

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

argparse.REMAINDER. Wszystkie pozostałe argumenty wiersza poleceń są zebrane w listę. Jest to zwykle przydatne w przypadku narzędzi wiersza polecenia, które są wysyłane do innych narzędzi wiersza polecenia

Jeśli nargsnie podano argumentu słowa kluczowego, liczba wykorzystanych argumentów jest określona przez działanie. Ogólnie oznacza to, że zużyty zostanie jeden argument wiersza poleceń i zostanie wygenerowany pojedynczy element (nie lista).

Edytuj (skopiowane z komentarza @Acumenus) nargs='?' Dokumenty mówią: „?”. Jeden argument zostanie wykorzystany z wiersza poleceń, jeśli to możliwe, i zostanie wygenerowany jako pojedynczy element. Jeśli nie ma argumentu wiersza poleceń, zostanie wygenerowana wartość domyślna.


3
Należy jednak zauważyć, że nargs='?'nie tworzy listy.
Acumenus,

@ABB Ostatni wiersz odpowiedzi Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced.Mam nadzieję, że to pomoże ...
Matas Vaitkevicius,

1
Cytowany wiersz odnosi się do przypadku nieokreślenia nargs, ale nargs='?'definiuje go. W docs powiedzieć: '?'. Jeden argument zostanie wykorzystany z linii poleceń, jeśli to możliwe, i zostanie wygenerowany jako pojedynczy element. Jeśli nie ma argumentu wiersza poleceń, zostanie wygenerowana wartość domyślna.
Acumenus,

@ABB Po prostu edytuj odpowiedź, jeśli uważasz, że czegoś brakuje. Dzięki.
Matas Vaitkevicius

Jaka jest różnica między nargs=argparse.REMAINDERi nargs='*', jak mi się wydaje, są identyczne pod względem działania (testowane w Python 2.7.10 i Python 3.6.1)?

-5

parser.add_argumentwymaga również przełącznika . Możesz użyć required=False. Oto przykładowy fragment kodu w Pythonie 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()

11
OP pytał o parametry pozycyjne, a nie „-dir”. „wymagany” jest nieprawidłowym argumentem dla pozycji. A „fałsz” był literówką, miała na myśli „fałsz”. +1 dla początkujących, -1 dla niechlujstwa.
SoloPilot,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.