2016-12-17 2 views
1

Ich habe eine Befehlszeilenoption, die ein Argument erfordert. Ich würde gerne "--" als Argument liefern können, aber ich kann nicht herausfinden, wie es geht.Wie kann ich argarse bekommen, "-" als Argument zu einer Option zu akzeptieren?

Beispielcode: (test-argparse.py)

#!/usr/bin/env python 

from __future__ import print_function 
import argparse 
import sys 


def main(argv): 
    ap = argparse.ArgumentParser() 
    ap.add_argument("-x", "--foo", metavar="VALUE", default="", 
        help="Test option.") 
    args = ap.parse_args(argv[1:]) 

    print(args.foo) 

if __name__ == "__main__": 
    sys.exit(main(sys.argv)) 

meine Versuche scheitern Alle zu versuchen "--" als Argument übergeben:

$ test-argparse.py --foo -- 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: argument -x/--foo: expected one argument 

$ test-argparse.py --foo -- -- 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: argument -x/--foo: expected one argument 

$ test-argparse.py --foo=-- 
[] 

$ test-argparse.py --foo=-- -- 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: unrecognized arguments: -- 

$ test-argparse.py --foo="--" 
[] 

$ test-argparse.py '--foo --' 
usage: test-argparse.py [-h] [-x VALUE] 
test-argparse.py: error: unrecognized arguments: --foo -- 

$ test-argparse.py -x-- 
[] 

$ test-argparse.py '-x --' 
-- 

Der letzte Fall ist, in der Nähe, aber es schließt den Raum (und ich kann whitespace nicht einfach löschen, denn was, wenn ich " " als Wert zulassen möchte?). Kann ich das irgendwie erreichen?

Diese argparse zwingt Argument Permutation auf Clients (was zu unnötiger Mehrdeutigkeit führt) ist sehr frustrierend.

(Ich verwende Python 2.7.12.)

+0

Ich rate '- foo = "-" ' –

+0

@ cricket_007 Nein. Druckt '[]'. – jamesdlin

+0

Grundsätzlich denke ich, dass Sie die Anführungszeichen um Ihre Zeichenfolge benötigen. Typische Bash-Programme trennen die Optionen und die restlichen Argumente durch Bindestriche. –

Antwort

2

Im Idealfall --foo=-- sollte funktionieren, aber der aktuelle Parser löscht alle '-', so dass eine leere Zeichenfolge an seiner Stelle, daher das foo=[] Ergebnis. Ich habe vor ein paar Jahren einen Patch vorgeschlagen, der das hätte beheben sollen, aber er ist im Rückstand argparse gefangen. http://bugs.python.org/issue13922, http://bugs.python.org/issue14364, http://bugs.python.org/issue9571

Python argparse with -- as the value schlägt Vorverarbeitung sys.argv zu ersetzen oder mehrere der -- mit noch etwas anderes.

Wenn Sie Spiel für das Patchen Ihrer argparse.py Datei (oder Unterklasse der ArgumentParser Klasse) sind, könnte ich meine früheren Arbeiten wieder besuchen und eine Lösung vorschlagen. Der Trick besteht darin, das =-- zu akzeptieren, aber immer noch das erste freie -- als das 'Rest-sind-Positionals'-Flag (und behalten Sie alle folgenden --). Leider ist eine Methode, die gepatcht werden muss, in einer viel größeren verschachtelt.

2

Es gibt einen bestimmten Grund, dass dies nicht funktioniert: -- bedeutet „dieses Token überspringen und den Rest der Argumente betrachten Lage zu sein, auch wenn sie Beginnen Sie mit einem Schuss. "

Viele, viele Programme akzeptieren kein -- als Argument, aber sie werden - akzeptieren. Der einzelne Strich ist sogar eine Standardmethode, um anstelle eines Dateinamens "Standardeingabe oder -ausgabe verwenden" zu verwenden.

Also das Beste, was Sie für die Benutzer Ihres Programms tun können, ist wahrscheinlich, es nicht -- zu erfordern, denn das ist nicht etwas, das normalerweise getan wird, und nicht etwas, das die meisten modernen Kommandozeilen-Parsing-Bibliotheken wahrscheinlich können analysieren.

Sie -- als Positions Option nutzen könnten, so könnten Sie wahrscheinlich unterstützen dies:

--foo -- -- 

Wenn Sie --foo machen action='store_true' (dh es ist eine Option kein Argument nehmen), plus eine nicht-obligatorischen Positions Streit. Das wird wahrscheinlich funktionieren, weil die erste -- bedeutet "bearbeite Striche als Optionen zu stoppen" und die zweite ist ein Positionsargument.

+0

Ich verstehe, was '--' normalerweise verwendet wird für, und ich verstehe, warum Argparse Probleme hat (weil es Argument Permutation tun will). Ich halte das nicht für eine Entschuldigung; Ein Token, das einer Option folgt, für die ein Argument erforderlich ist, sollte als Argument dieser Option behandelt werden. Leider habe ich keine Wahl, als Argument "-" zuzulassen; Das Argument kann eine beliebige Zeichenfolge sein. – jamesdlin

+0

@jamesdlin: Klar, dann kannst du es als Positionsargument unterstützen. Ich fügte meiner Antwort etwas hinzu und erklärte, wie. –

+0

Sorry, kein Up-Vote für ein "wird wahrscheinlich funktionieren" ... – martineau

Verwandte Themen