Ten problem został szczegółowo omówiony w artykule http://bugs.python.org/issue9334. Większość działań była w 2011 roku. Dodałem łatkę w zeszłym roku, ale jest sporo zaległości w łatkach argparse
.
Kwestia jest potencjalną niejednoznacznością w ciągu znaków takim jak '--env'
lub "-s WHATEVER -e COOL STUFF"
, gdy następuje po opcji, która przyjmuje argument.
optparse
wykonuje proste przetwarzanie od lewej do prawej. Pierwszy --env
jest flagą opcji, która przyjmuje jeden argument, więc zużywa następny, niezależnie od tego, jak wygląda. argparse
, z drugiej strony, pętle przez ciągi dwa razy. Najpierw klasyfikuje je jako "O" lub "A" (flaga lub argument opcji). W drugiej pętli zużywa je, używając dopasowywania wzorców w celu uzyskania wartości zmiennych nargs
. W tym przypadku wygląda na to, że mamy OO
, dwie flagi i żadnych argumentów.
Rozwiązaniem przy użyciu argparse
jest upewnienie się, że ciąg argumentów nie zostanie pomylony dla flagi opcji. Możliwości, które zostały pokazane tutaj (iw kwestii bug) obejmują:
--env="--env" # clearly defines the argument.
--env " --env" # other non - character
--env "--env " # space after
--env "--env one two" # but not '--env "-env one two"'
Sama '--env'
wygląda flaga (nawet gdy cytowany zobaczyć sys.argv
), ale kiedy następuje innych strunach nie. Ale "-env one two"
ma problemy, ponieważ może być przetwarzany jako ['-e','nv one two']
, flaga `` -e ', po której następuje ciąg (lub jeszcze więcej opcji).
--
i nargs=argparse.PARSER
może być również użyty do wymuszenia na argparse
wyświetlania wszystkich poniższych łańcuchów jako argumentów. Ale działają tylko na końcu listy argumentów.
Istnieje proponowana łatka w numerze9334, aby dodać tryb args_default_to_positional=True
. W tym trybie parser klasyfikuje tylko łańcuchy jako flagi opcji, jeśli może jednoznacznie dopasować je do zdefiniowanych argumentów. Tak więc "--one" w "--env --one" zostanie zaklasyfikowane jako argument. Ale drugi "--env" w "--env --env" nadal będzie klasyfikowany jako flaga opcji.
Rozszerzając podobnego przypadku w
Using argparse with argument values that begin with a dash ("-")
parser = argparse.ArgumentParser(prog="PROG")
parser.add_argument("-f", "--force", default=False, action="store_true")
parser.add_argument("-e", "--extra")
args = parser.parse_args()
print(args)
produkuje
1513:~/mypy$ python3 stack16174992.py --extra "--foo one"
Namespace(extra='--foo one', force=False)
1513:~/mypy$ python3 stack16174992.py --extra "-foo one"
usage: PROG [-h] [-f] [-e EXTRA]
PROG: error: argument -e/--extra: expected one argument
1513:~/mypy$ python3 stack16174992.py --extra "-bar one"
Namespace(extra='-bar one', force=False)
1514:~/mypy$ python3 stack16174992.py -fe one
Namespace(extra='one', force=True)
W "-foo jeden" przypadek nie dlatego, że -foo
jest interpretowane jako flagi -f
plus nieokreślone dodatki. Jest to ta sama czynność, która umożliwia interpretowanie -fe
jako ['-f','-e']
.
Jeśli zmienię nargs
do REMAINDER
(nie PARSER
), wszystko po -e
jest interpretowany jako argumenty dla tej flagi:
parser.add_argument("-e", "--extra", nargs=argparse.REMAINDER)
wszystkich przypadkach praca. Zauważ, że wartość jest listą. I cytaty nie są potrzebne:
1518:~/mypy$ python3 stack16174992.py --extra "--foo one"
Namespace(extra=['--foo one'], force=False)
1519:~/mypy$ python3 stack16174992.py --extra "-foo one"
Namespace(extra=['-foo one'], force=False)
1519:~/mypy$ python3 stack16174992.py --extra "-bar one"
Namespace(extra=['-bar one'], force=False)
1519:~/mypy$ python3 stack16174992.py -fe one
Namespace(extra=['one'], force=True)
1520:~/mypy$ python3 stack16174992.py --extra --foo one
Namespace(extra=['--foo', 'one'], force=False)
1521:~/mypy$ python3 stack16174992.py --extra -foo one
Namespace(extra=['-foo', 'one'], force=False)
argparse.REMAINDER
jest jak „*”, oprócz tego, że bierze wszystko, co poniżej, czy to wygląda jak flaga czy nie. argparse.PARSER
jest bardziej podobny do "+", ponieważ spodziewa się najpierw argumentu podobnego do positional
. Użyty jest numer nargs
.
używa od REMAINDER
jest udokumentowana, https://docs.python.org/3/library/argparse.html#nargs
Jaka wersja Pythona używasz? – William
Używam Pythona 2.7. – sfendell
Działa to dobrze dla mnie w Pythonie 2.7. Czy masz skonfigurowane inne * argumenty *? –