784 Stimmen

Wie kann ich eine Liste als Kommandozeilenargument mit argparse übergeben?

Ich versuche, eine Liste als Argument an ein Befehlszeilenprogramm zu übergeben. Gibt es eine argparse Option zur Übergabe einer Liste als Option?

parser.add_argument('-l', '--list',
                      type=list, action='store',
                      dest='list',
                      help='<Required> Set flag',
                      required=True)

Das Skript wird wie folgt aufgerufen

python test.py -l "265340 268738 270774 270817"

9voto

kfsone Punkte 22501

Wenn Sie beabsichtigen, einen einzelnen Schalter mit mehreren Parametern zu versehen, verwenden Sie nargs='+' . Wenn Ihr Beispiel "-l" tatsächlich ganze Zahlen nimmt:

a = argparse.ArgumentParser()
a.add_argument(
    '-l', '--list',  # either of this switches
    nargs='+',       # one or more parameters to this switch
    type=int,        # /parameters/ are ints
    dest='lst',      # store in 'lst'.
    default=[],      # since we're not specifying required.
)

print a.parse_args("-l 123 234 345 456".split(' '))
print a.parse_args("-l 123 -l=234 -l345 --list 456".split(' '))

Erzeugt

Namespace(lst=[123, 234, 345, 456])
Namespace(lst=[456])  # Attention!

Wenn Sie das gleiche Argument mehrmals angeben, wird die Standardaktion ( 'store' ) ersetzt die vorhandenen Daten.

Die Alternative ist die Verwendung der append Aktion:

a = argparse.ArgumentParser()
a.add_argument(
    '-l', '--list',  # either of this switches
    type=int,        # /parameters/ are ints
    dest='lst',      # store in 'lst'.
    default=[],      # since we're not specifying required.
    action='append', # add to the list instead of replacing it
)

print a.parse_args("-l 123 -l=234 -l345 --list 456".split(' '))

Das erzeugt

Namespace(lst=[123, 234, 345, 456])

Oder Sie können einen benutzerdefinierten Handler/Aktion schreiben, um kommagetrennte Werte zu parsen, so dass Sie Folgendes tun können

-l 123,234,345 -l 456

6voto

wonder.mice Punkte 6676

Unter add_argument() , type ist lediglich ein aufrufbares Objekt, das eine Zeichenkette empfängt und einen Optionswert zurückgibt.

import ast

def arg_as_list(s):                                                            
    v = ast.literal_eval(s)                                                    
    if type(v) is not list:                                                    
        raise argparse.ArgumentTypeError("Argument \"%s\" is not a list" % (s))
    return v                                                                   

def foo():
    parser.add_argument("--list", type=arg_as_list, default=[],
                        help="List of values")

Dies wird es ermöglichen:

$ ./tool --list "[1,2,3,4]"

4voto

Nebulastic Punkte 7640

Ich denke, die eleganteste Lösung ist, eine Lambda-Funktion an "type" zu übergeben, wie von Chepner erwähnt. Darüber hinaus können Sie, wenn Sie nicht im Voraus wissen, welches Trennzeichen Ihre Liste haben wird, auch mehrere Trennzeichen an re.split übergeben:

# python3 test.py -l "abc xyz, 123"

import re
import argparse

parser = argparse.ArgumentParser(description='Process a list.')
parser.add_argument('-l', '--list',
                    type=lambda s: re.split(' |, ', s),
                    required=True,
                    help='comma or space delimited list of characters')

args = parser.parse_args()
print(args.list)

# Output: ['abc', 'xyz', '123']

2voto

Meysam Sadeghi Punkte 988

Wenn Sie eine verschachtelte Liste haben, bei der die inneren Listen unterschiedliche Typen und Längen haben und Sie den Typ beibehalten möchten, z. B.,

[[1, 2], ["foo", "bar"], [3.14, "baz", 20]]

dann können Sie die Lösung verwenden, die von @sam-mason a diese Frage wie unten dargestellt:

from argparse import ArgumentParser
import json

parser = ArgumentParser()
parser.add_argument('-l', type=json.loads)
parser.parse_args(['-l', '[[1,2],["foo","bar"],[3.14,"baz",20]]'])

das ergibt:

Namespace(l=[[1, 2], ['foo', 'bar'], [3.14, 'baz', 20]])

1voto

Leonard Punkte 2008

Sie können die Liste als Zeichenkette parsen und mit der eval Funktion, um sie als Liste zu lesen. In diesem Fall müssen Sie einfache Anführungszeichen in doppelte Anführungszeichen umwandeln (oder umgekehrt), damit die Zeichenkette erfolgreich geparst werden kann.

# declare the list arg as a string
parser.add_argument('-l', '--list', type=str)

# parse
args = parser.parse()

# turn the 'list' string argument into a list object
args.list = eval(args.list)
print(list)
print(type(list))

Prüfung:

python list_arg.py --list "[1, 2, 3]"

[1, 2, 3]
<class 'list'>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X