защо args.add_argument работи, когато е даден в два отделни израза, но не и в един в python?

Опитвам се да използвам модула argparse, за да анализирам аргументите в командния ред. ето примерния код

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar')
parser.add_argument('-foo')
args=parser.parse_args()
print args

стартиране на това

python argparsing.py "hello"
Namespace(bar='hello', foo=None)

това обаче не работи

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar','--foo')
#parser.add_argument('-foo')
args=parser.parse_args()
print args

изпълнявайки това дава грешка

python argparsing.py "hello"
Traceback (most recent call last):
  File "argparsing.py", line 3, in <module>
    parser.add_argument('bar','-foo')
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1267, in add_argument
    kwargs = self._get_optional_kwargs(*args, **kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1397, in _get_optional_kwargs
    raise ValueError(msg % tup)
ValueError: invalid option string 'bar': must start with a character '-'

Единствената разлика между двете е, че добавям аргумент отделно (в два реда) в първия код, но ги добавям в същия ред като едно изявление в неуспешния код. може ли някой да ми помогне да разбера това по-добре?


person eagertoLearn    schedule 01.10.2013    source източник


Отговори (3)


Не правиш същото. Вижте документите:

име или флагове - Или име, или списък с опционални низове, напр. foo или -f, --foo.

Не можете да зададете списък с позиционни аргументи, само един позиционен аргумент или списък с аргументи за опция (флаг). Така че, когато се опитате да му дадете 'bar', '--foo', той се опитва да анализира 'bar' като опция и не може, защото не започва с -.

И както обяснява следващият раздел, когато давате това е списък с опции, вие му давате списък с алтернативни имена за един и същ флаг, а не куп отделни флагове. Така че не искате да правите това, което се опитвате да направите на първо място.

person abarnert    schedule 01.10.2013
comment
това означава ли, че parser.add_argument('-f', '--foo-bar', '--foo')', results in only flag in which f, foo-bar и foo` са еквивалентни? - person eagertoLearn; 02.10.2013
comment
@user2708477: Да. Но можете да опитате и да се убедите сами точно толкова лесно, колкото можете да поискате. Ако parse_args(['-fspam', '--foo=eggs']) или стартирате програмата с python argparsing.py -fspam --foo=eggs, ще получите Namespace(foo_bar='eggs'). - person abarnert; 02.10.2013
comment
@user2708477: Освен това, ако прочетете документите, трябва да е очевидно, че всички дадени флагове ще завършат с едни и същи action, dest и т.н. Как иначе би работило? Освен това... вашият пример е знак за знак, идентичен с един от примерите в документите, под dest, което вече показва какво се случва. - person abarnert; 02.10.2013
comment
съжалявам, малко съм объркан. когато стартирам този python argparsing.py -fspam -f=eggs, получавам Namespace(foo_bar='eggs'). как бих могъл, foo_bar = egg, когато задам -f=eggs в командния ред - person eagertoLearn; 02.10.2013
comment
@user2708477: Защото -f, --foo-bar и --foo са една и съща опция. Ако не предоставите dest за тази опция: ArgumentParser генерира стойността на dest, като вземе първия дълъг низ от опции и премахне първоначалния низ --. Всичко е обяснено в документите, които свързах за вас. И написаното в документите е много по-добро от написаното в моите коментари. - person abarnert; 02.10.2013

add_argument има за цел да добави единичен аргумент. 'bar' е един позиционен аргумент; '--foo' е един незадължителен аргумент. Не можете да направите аргумент, който е едновременно позиционен и незадължителен, оттук и грешката.

Ако искате да дефинирате аргумент, но именувате опцията по различен начин, използвайте dest:

# accept an option --foo X, and store X into args.bar
parser.add_argument('--foo', dest='bar')

Имайте предвид, че можете да дефинирате множество псевдоними за един незадължителен аргумент, напр.

parser.add_argument('-f', '--foo', '--frobnicate')
person nneonneo    schedule 01.10.2013
comment
в документите се добавят множество незадължителни аргументи, напр. parser.add_argument('-f', '--foo-bar', '--foo'). - person eagertoLearn; 02.10.2013
comment
@user2708477: всички те са псевдоними за незадължителен аргумент. Опитахте се да дефинирате аргумент, който е едновременно позиционен и незадължителен. - person nneonneo; 02.10.2013

Така че вие ​​давате на argparse два напълно различни начина за дефиниране на аргумент. Така че извежда грешка, защото не може да разбере въведеното от вас

Един метод за дефиниране на аргумент е да не използвате тирета, както сте имали преди

parser.add_argument("bar")  # This is a required argument

Друг е да използвате тирета

parser.add_argument("-f", "--foo")  

--foo е просто друг начин за указване на същия аргумент като -f. Това не е задължителен аргумент като тези без тирета (bar), освен ако не искате да бъде задължителен аргумент

person Greg    schedule 01.10.2013