2013-04-02 15 views
22

Chciałbym dokonać tych wywołań pracy myprog, a nie innych.jak uczynić argument opcjonalnym w python argparse

$ python3 myprog.py -i infile -o outfile 
$ python3 myprog.py -o outfile 
$ python3 myprog.py -o 
$ python3 myprog.py 

W szczególności chcę, aby to nielegalne określić plik_we ale nie plik_wy.

W trzecim przypadku przyjmuje się domyślną nazwę pliku wyjściowego "out.json". W drugim, trzecim i czwartym przypadku przyjmuje się domyślną nazwę pliku wejściowego "file.n.json", gdzie n jest liczbą całkowitą wersji. W czwartym przypadku plikiem wyjściowym będzie "file.n + 1.json", gdzie n + 1 jest wersją numer jeden większą niż ta na pliku wejściowym. Odpowiedni fragment mojego kodu jest:

import argparse 

parser = argparse.ArgumentParser(description="first python version") 
parser.add_argument('-i', '--infile', nargs=1, type=argparse.FileType('r'), help='input file, in JSON format') 
parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format') 

args = parser.parse_args() 

print("Here's what we saw on the command line: ") 
print("args.infile",args.infile) 
print("args.outfile",args.outfile) 

if args.infile and not args.outfile: 
    parser.error("dont specify an infile without specifying an outfile") 
elif not args.infile: 
    print("fetching infile") 
else: # neither was specified on the command line 
    print("fetching both infile and outfile") 

Problem jest, gdy biegnę

$ python3 myprog.py -i infile.json 

zamiast błędu parsera się spodziewałem, otrzymuję:

Here's what we saw on the command line: 
args.infile [<_io.TextIOWrapper name='infile.json' mode='r' encoding='UTF-8'>] 
args.outfile <_io.TextIOWrapper name='out.json' mode='w' encoding='UTF-8'> 
fetching both infile and outfile 

... co sugeruje, że nawet jeśli nie było "-o" na linii poleceń, działało to tak, jakby było.

+0

Jaka jest różnica między trzecim a czwartym przypadkiem? co oznacza "-o"? –

+0

Czwarty przypadek będzie używał domyślnych nazw plików typu "plik-plik" i "plik wyjściowy" (szczególnie file.n.json i file.n + 1.json, tzn. Pliki z osadzonymi numerami wersji). Różnią się one od "out.json", co spowodowałoby trzeci przypadek z opcją "-o". Zmodyfikowałem powyższy tekst, aby to zaznaczyć. – user1416227

+0

Jak działa czwarty przypadek, ponieważ opcja '--input' nie ma wartości domyślnej? – maxschlepzig

Odpowiedz

10

Podałeś domyślny argument dla pliku wyjściowego.

parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format') 

Jeśli opcja -o nie jest określony w linii poleceń, parser arg wstawia domyślny argument.

Zmień to:

parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), help='output file, in JSON format') 

i wszystko powinno działać zgodnie z oczekiwaniami.


Jeśli chcesz być w stanie określić -o, bez nazwy pliku, prawdopodobnie chcesz coś takiego:

out_file = args.out if args.out is not None else 'json.out'

Nie jestem pewien, czy istotnym parametrem będzie None lub '' (tj. pusty ciąg), jeśli podasz -o bez parametru - podejrzewam, że jest to None, ale nie wiem na pewno. Musisz to przetestować, żeby się upewnić.

Nie wiem jak to zrobić bez dodatkowej logiki z argparse.

+1

To prawie dokładnie to, czego chcę. Pozostały problem polega na tym, że chcę, aby '$ python3 myprog.py -o' działało tak, jakbym uruchomił' $ python3 myprog.py -o out.json'. Czy możesz zasugerować, jak to zrobić? – user1416227

+0

Dzięki! Myślałem, że mogę to zrobić z argparse. – user1416227

+0

Ta odpowiedź ignoruje wymagania trzeciego przypadku z pytania. Zobacz odpowiedź maximiego na to, jak można zaimplementować trzeci przypadek z argparse. Ostatnie przypisanie nie ma nawet prawidłowej składni Pythona. – maxschlepzig

13

Jako dodatek do wybranego odpowiedź:

możliwości uruchomienia -o bez określenia pliku, można to zrobić za pomocą const połączeniu z nargs='?'.

Od docs:

Kiedy add_argument() jest wywoływana z ciągów opcji (jak -f lub --foo) i nargs = '?'. Spowoduje to utworzenie opcjonalnego argumentu, który można wykonać za pomocą zerowego lub jednego argumentu wiersza polecenia: .Podczas analizowania wiersza polecenia, , jeśli napotkano łańcuch opcji, bez następującego po nim argumentu wiersza poleceń, zostanie przyjęta wartość const. Zapoznaj się z opisami na temat nargs z .

+0

To powinna być poprawna odpowiedź. Dzięki!! – jbo5112

Powiązane problemy