2017-03-21 3 views
2

Ich benutze Python 2.7.13.Pythons argparse Standardwert funktioniert nicht

Mein Ziel ist es drei mögliche Argumente zu haben, mit Standardwerten gesetzt werden, wenn keine Argumente vom Benutzer angegeben:

parser.add_argument("-r", nargs=3, default=(0, 1000, 50), type=int, help="Useful help text") 

Dies gilt nicht für mich arbeiten, und ich kann nicht überall finden, wenn Es ist möglich, den Standard wie oben zu verwenden.

Wenn es als program.py -r Laufen bekomme ich einen einen Fehler: expected 3 Argument (e)

Aber ich habe auch versucht, nargs vollständig und nur mit einem Standardwert zu entfernen:

parser.add_argument("-r", default=100) 

Merkwürdigerweise dieses funktioniert auch nicht. Es erfordert mindestens ein Argument ...

Wer versteht das?

+0

Wenn Sie mit program.py -r ausführen, erwartet die argparse einige Parameter. Wenn Sie das Flag -r überspringen, werden Standardwerte verwendet. – rammelmueller

Antwort

1

Sie müssen nur das Argument -r aufrufen, wenn Sie nicht den Standardwert verwenden. Wenn Sie anrufen, müssen Sie auch einen Wert übergeben (oder so viele Werte, wie Sie in nargs definieren).

Versuchen Sie nur fragen program.py

+0

Okay, aber was mache ich, wenn ich -r verwenden möchte, egal was? Da ich auch andere Flags habe, möchte ich -r mit oder ohne Argumente verwenden können. Und natürlich, Standardwerte, wenn keine Argumente gegeben wurden. Ist das möglich? – AltoBalto

+0

Was soll '-r' ohne Argumente tun? – hpaulj

+0

Wenn Sie program.py ohne Flags aufrufen, implizieren Sie, dass Sie Standardwerte für alle Flags möchten. Wenn nicht, hättest du das sagen sollen;) Also, wenn du -r mit Standardwerten verwenden willst, erwähne es einfach nicht und lass argarse ihm stillschweigend seinen Standardwert zuweisen. Wenn Sie aus irgendeinem Grund nur erwähnen müssen, übergeben Sie einfach den Standardwert explizit. – mknull

0

Warum Sie argv nicht verwenden?

Beispiel:

import sys 

def main(first=1, second=2, third=3): 
    print first,second,third 

if __name__ == '__main__': 
    main(*sys.argv[1:])  # notice the * before sys.argv[1:] 

Sie testen können Sie die Datei von der Konsole mit unterschiedlicher Anzahl von Parametern ausführen:

python myprogram.py   # will print 1 2 3 
python myprogram.py 7  # will print 7 2 3 
python myprogram.py 7 8  # will print 7 8 3 
python myprogram.py 7 8 9 # will print 7 8 9 
+0

Was bedeutet * vor sys.argv? – AltoBalto

0

Mit Ihrem Beispiel können Sie entweder die Anwendung aufrufen, ohne die -r Flagge, die zur Folge hätte in den Standardwerten. Wenn Sie die Werte selbst angeben möchten, müssen Sie alle angeben.

Wenn Sie sie Sie so etwas wie diese könnten versuchen, unabhängig geben möchten: konnte

$ python script.py 
Namespace(r=(0, 1000, 50)) 
$ python script.py -r 1 2 3 
Namespace(r=[1, 2, 3]) 
$ python script.py -r 1 
usage: args.py [-h] [-r R R R] 
args.py: error: argument -r: expected 3 arguments 

Verwendung separater Argumente Ihre Beschwörungen:

# script.py 
import argparse 

def main1(): 
    parser = argparse.ArgumentParser() 
    parser.add_argument("-r", nargs=3, default=(0, 1000, 50), type=int, 
         help="Useful help text") 
    args = parser.parse_args() 
    print(args) 

def main2(): 
    parser = argparse.ArgumentParser() 
    parser.add_argument("-r1", type=int, default=0, help="...") 
    parser.add_argument("-r2", type=int, default=1000, help="...") 
    parser.add_argument("-r3", type=int, default=50, help="...") 
    args = parser.parse_args() 
    print(args) 

if __name__ == "__main__": 
    main1() 
    #main2() 

Sie Ihre Implementierung (main1) wie folgt aufrufen könnte so aussehen (main2):

$ python script.py -r1 1 -r2 2 -r3 3 
Namespace(r1=1, r2=2, r3=3) 
$ python script.py -r1 1 
Namespace(r1=1, r2=1000, r3=50) 
$ python script.py -r2 2 
Namespace(r1=0, r2=2, r3=50) 
$ python script.py -r3 3 
Namespace(r1=0, r2=1000, r3=3) 

Dies könnte ein bisschen wortreicher sein, wenn Sie alle Werte ändern möchten, aber es gibt Ihnen mehr Flexibilität. Ich denke, Sie könnten diese beiden Ansätze sogar mit einem mutually_exclusive_group kombinieren.

3

Ich werde das normale Verhalten von default in argparse (mit einer IPython interaktiven Sitzung) zeigen

In [32]: parser = argparse.ArgumentParser() 

3 Aktionen definieren:

In [33]: parser.add_argument('-r', nargs=3, type=int, default=(1,2,3)); 
In [35]: parser.add_argument('-f', default='DEFAULT'); 
In [37]: parser.add_argument('-g', nargs='?', default='DEFAULT', const='const'); 

Die help.Beachten Sie, dass alle Aktionen haben [], was darauf hinweist, daß sie optional sind:

In [39]: parser.print_help() 
usage: ipython3 [-h] [-r R R R] [-f F] [-g [G]] 

optional arguments: 
    -h, --help show this help message and exit 
    -r R R R 
    -f F 
    -g [G] 

Wenn ohne argments genannt, alle Standardeinstellungen erscheinen im args Namespace.

In [40]: parser.parse_args([]) # e.g python myprog.py 
Out[40]: Namespace(f='DEFAULT', g='DEFAULT', r=(1, 2, 3)) 

Geben -r mit 3 Zahlen (wie durch die nargs angegeben)

In [41]: parser.parse_args('-r 4 5 6'.split()) 
Out[41]: Namespace(f='DEFAULT', g='DEFAULT', r=[4, 5, 6]) 

einer der anderen Flags angeben. Beachten Sie die übrigen Standardwerte

In [42]: parser.parse_args('-f other'.split()) 
Out[42]: Namespace(f='other', g='DEFAULT', r=(1, 2, 3)) 

-g mit nargs='?' eine andere Option hat. Es kann ohne Argumente angegeben werden. In diesem Fall erhält es den const Wert.

In [43]: parser.parse_args('-f other -g'.split()) 
Out[43]: Namespace(f='other', g='const', r=(1, 2, 3)) 
In [44]: parser.parse_args('-f other -g more'.split()) 
Out[44]: Namespace(f='other', g='more', r=(1, 2, 3)) 

Es ist nicht so eine 3-Wege-Option für nargs=3. Sie geben entweder die 3 Werte an oder Sie verwenden -r nicht. Wenn Sie zwischen 1) no-r-Flag, 2) r-Flag ohne Argumente und 3) r flat mit 3 Argumenten unterscheiden müssen, würde ich vorschlagen, Funktionalität in 2 Aktionen aufzuteilen, eine 'store_true' und andere, die die 3 Werte.

Defaults in argparse kann eine komplizierte Angelegenheit sein, mit verschiedenen Möglichkeiten, sie zu setzen, Unterschiede zwischen String-und Nicht-String-Werte, sogar eine Möglichkeit, sie zu unterdrücken. Aber ich habe das grundlegende Verhalten gezeigt.

Verwandte Themen