2013-06-18 10 views
5

Jak zdefiniować dowolny ciąg jako opcjonalny argument za pomocą argparse?python - Używając argparse, przekaż dowolny ciąg jako argument do użycia w skrypcie

Przykład:

[[email protected]]$ ./script.py FOOBAR -a -b 
Running "script.py"... 
You set the option "-a" 
You set the option "-b" 
You passed the string "FOOBAR" 

Idealnie chciałbym pozycję argumentów nie ma znaczenia. tj:

./script.py -a FOOBAR -b == ./script.py -a -b FOOBAR == ./script.py FOOBAR -a -b


w bash, można to osiągnąć podczas korzystania getopts. Po pracy wszystkie żądane przełączniki w przypadku pętli, musiałbym linię, która czyta shift $((OPTIND-1)), a stamtąd można uzyskać dostęp do wszystkich pozostałych argumentów używając średnia $1, $2, $3, etc ...
Czy coś takiego exisit dla argparse?

+3

Czy przechodziłeś przez samouczek argparse? Wszystko, co opisujesz, jest tam. – SheetJS

+0

Jedyną nie omawianą częścią iirc jest zachowanie 'nargs =" * "' (tak, że jeden argument pozycyjny może pobrać wszystkie pozostałe argumenty) – SheetJS

+1

@Nirk, Trudne jest to, że jeśli po prostu użyjesz 'parse_args', gdy tylko zobaczy argument" pozycyjny ", przestaje szukać innych argumentów i zbiera argumenty z argumentu pozycyjnego na koniec. W większości przypadków jest to w porządku, ale złamałby pierwszy i trzeci przykład. – jedwards

Odpowiedz

6

Aby dostać dokładnie to, czego szukasz, sztuką jest wykorzystanie parse_known_args() zamiast parse_args():

#!/bin/env python 

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('-a', action="store_true") 
parser.add_argument('-b', action="store_true") 

opts = parser.parse_known_args() 
# Print info about flags 
if opts[0].a: print('You set the option "-a"') 
if opts[0].b: print('You set the option "-b"') 
# Collect remainder (opts[1] is a list (possibly empty) of all remaining args) 
if opts[1]: print('You passed the strings %s' % opts[1]) 

EDIT:

Powyższy kod wyświetla następujące informacje pomocy:

 
./clargs.py -h 

usage: clargs_old.py [-h] [-a] [-b] 

optional arguments: 
    -h, --help show this help message and exit 
    -a 
    -b 

Jeśli chcesz poinformować użytkownika o opcjonalnym dowolnym argumencie, jedynym rozwiązaniem, jakie mogę wymyślić jest podklasa ArgumentParser i zapisz to w sobie.

Na przykład:

#!/bin/env python 

import os 
import argparse 

class MyParser(argparse.ArgumentParser): 
    def format_help(self): 
     help = super(MyParser, self).format_help() 
     helplines = help.splitlines() 
     helplines[0] += ' [FOO]' 
     helplines.append(' FOO   some description of FOO') 
     helplines.append('') # Just a trick to force a linesep at the end 
     return os.linesep.join(helplines) 

parser = MyParser() 
parser.add_argument('-a', action="store_true") 
parser.add_argument('-b', action="store_true") 

opts = parser.parse_known_args() 
# Print info about flags 
if opts[0].a: print('You set the option "-a"') 
if opts[0].b: print('You set the option "-b"') 
# Collect remainder 
if opts[1]: print('You passed the strings %s' % opts[1]) 

który wyświetla następujące informacje pomocy:

 
./clargs.py -h 

usage: clargs.py [-h] [-a] [-b] [FOO] 

optional arguments: 
    -h, --help show this help message and exit 
    -a 
    -b 
    FOO   some description of FOO 

Uwaga dodanie [FOO] w wierszu „użytkowania” i FOO w pomocy w sekcji „argumentów opcjonalnych ".

+0

To jest dobre, z wyjątkiem tego, że tracę wbudowane okno dialogowe pomocy z argparse dla opcjonalnego łańcucha znaków. – svenglar

+1

To prawda. Jedyne rozwiązanie, jakie mogę wymyślić to podklasę ArgumentParser i napisanie jej w sobie. Zauważ, że jedynym powodem, dla którego musisz przeskoczyć przez ten obręcz, jest to, że chcesz, aby wszystkie argumenty zadziałały.Będę edytować moją odpowiedź na przykładzie podklasy ArgumentParser. – jedwards

+0

Wow, dzięki! Wydaje się dziwne, że nie ma opcji w argarse, aby opcjonalny argument był dowolnym ciągiem ... no cóż. Dziękuję bardzo za tę odpowiedź. – svenglar

Powiązane problemy