2013-04-23 1 views
33

두 개의 따옴표 사이에 argparse가 단일 인수로 인식하도록 만드는 방법이 있습니까?인용 부호가있는 문자열을 대시로 읽으려면 argparse를 얻을 수 없습니까?

mainparser = argparse.ArgumentParser() 
subparsers = mainparser.add_subparsers(dest='subcommand') 
parser = subparsers.add_parser('queue') 
parser.add_argument('-env', '--extraEnvVars', type=str, 
         help='String of extra arguments to be passed to model.') 
...other arguments added to parser... 

하지만 실행할 때 :

:

python Application.py queue -env "-s WHATEVER -e COOL STUFF" 

를 그것은 나에게주는이

내가 좋아하는 뭔가를 대시를보고, 그것을 새로운 옵션의 시작이 있다고 가정 유지하는 것

Application.py queue: error: argument -env/--extraEnvVars: expected one argument 

첫 번째 대시를 사용하지 않으면 완전히 정상적으로 작동하지만 중요한 것은 그 안에 대시가있는 문자열을 전달할 수 있습니다. 나는 그것을 성공하게하지만 \를 인수 문자열에 추가하는 \로 이스케이프를 시도했습니다.이 문제를 해결하는 방법을 아는 사람이 있습니까? 이것은 -s가 파서의 인수인지 여부에 관계없이 발생합니다.

편집 : Python 2.7을 사용하고 있습니다.

EDIT2 :

python Application.py -env " -env" 

작품 완벽하게 잘하지만

python Application.py -env "-env" 

하지 않습니다.

EDIT3 : 벌써 벌써 논쟁중인 버그 인 것 같습니다 : http://www.gossamer-threads.com/lists/python/bugs/89529, http://python.6.x6.nabble.com/issue9334-argparse-does-not-accept-options-taking-arguments-beginning-with-dash-regression-from-optp-td578790.html. 2.7에 불과하고 optparse가 아닙니다.

EDIT4 : 현재 열려있는 버그 리포트 : http://bugs.python.org/issue9334

+0

https://docs.python.org/3/library/argparse.html#nargs를 사용하는 파이썬의 버전은 무엇

이 설명되어 있습니다 REMAINDER의 사용? – William

+0

파이썬 2.7을 사용하고 있습니다. – sfendell

+0

파이썬 2.7에서 잘 돌아 간다. 다른 * 인수가 구성되어 있습니까? –

답변

9

매우 간단한 해결 방법으로 공백으로 인수를 시작할 수 있습니다. python tst.py -e ' -e blah' 원한다면 간단히 lstrip() 옵션을 정상으로 되돌릴 수 있습니다.

첫 번째 하위 인수가 원래 함수의 유효한 인수가 아닌 경우 아무 것도 수행하지 않아도됩니다. 즉, python tst.py -e '-s hi -e blah'이 작동하지 않는 유일한 이유는 -stst.py의 유효한 옵션이기 때문입니다.

더 이상 사용되지 않는 optparse 모듈도 문제없이 작동합니다.

+0

-s가 서브 파서에 유효한 옵션이기 때문에 문제가 발생하지 않는다고 생각합니다. 나는 이것을 시도했다 python Application.py queue -e "-notarealoption" 그리고 같은 오류가 발생했다. lstrip을 사용하는 것이 +를 대체하는 것보다 낫습니다. SethMMorton이 제안한 것처럼 보이지만 실제로는 내부에 아무 것도 대체되지 않거나 변경되거나/argparse가 읽지 않는 문자열을 인용 할 수있는 방법이 있어야합니다. – sfendell

+1

정말요? 나는 지금 당장 나의 짧은 시험에서 그 가정을 근거로 삼았다. 나는 하나의 인자'-a'를 취한 스크립트를 만들었고 간단히'-a '-b hello'를 보냈는데 잘 동작했다. 하지만 다른 버전의 Python을 사용하고 있습니다. – William

+1

나는 원래의 질문을 편집했다. 분명히 이것은> 2.7에서 argparse의 알려진 버그입니다. (. 파서를 호출하기 전에 sys.argv가 변경되었습니다.parse_args()를 사용하여 -env 옵션의 시작 부분에 더미 문자를 추가 한 다음 나중에 제거합니다. 그것은 지옥과 같은 해키하고 unpythonic지만 마침내 내가 원하는 걸 얻었습니다. – sfendell

33

업데이트 답 :

당신은 당신이 그것을 호출 할 때 등호 넣을 수 있습니다 :

python Application.py -env="-env" 

원래 답변 :

나는 또한 당신이하려는 일을하는 데 어려움을 겪었지만, 해결 방안은 argparse에있다. 이것은 parse_known_args 메쏘드이다. 이렇게하면 정의되지 않은 모든 인수가 파서를 통과하여 하위 프로세스에 사용한다는 가정하에 전달됩니다. 단점은 잘못된 인수로 오류를보고하지 않으며 옵션과 하위 프로세스의 옵션간에 충돌이 없는지 확인해야한다는 것입니다.

python Application.py -e "+s WHATEVER +e COOL STUFF" 

다음은 '+'로 변경 '-'사후 처리에 서브 프로세스에 전달하기 전에 :

또 다른 옵션은 대신에 마이너스의 플러스를 사용하는 사용자를 강제로 수 있습니다.

+1

parse_known_args가 도움이된다고 생각지 않습니다. 저는 따옴표에있는 주장을 읽으 려하지 않습니다. 따옴표 붙은 문자열을 단일 개체로 -env로 전달하고 싶습니다. 나는 후행 처리 경로를 고려해 봤는데, 여기에서 더 좋은 대답을 얻지 못하면 아마 나올 것이다.하지만 해키가 느껴진다. 문자열의 + 문자가 -로 바뀐다는 것을 의미한다. 나는 정말로 그 안에 어떤 문자들로 된 문자열을 전달할 수 있기를 바란다. – sfendell

+1

당신이 묻고있는 것을 봅니다 ... 따옴표없이 여러 문자열을 읽으려면'-env'에 하나 이상의 문자열을 읽도록 지시하는'nargs = '+''를 사용하십시오. – SethMMorton

+0

하지만 그 중 일부 문자열은 대시를 사용하고 하위 파서의 인수와 동일한 이름을 사용하고 싶습니다. python Application.py queue -env "-env blah"와 같은 것이 작동해야합니다. – sfendell

11

이 문제는 http://bugs.python.org/issue9334에서 자세히 논의됩니다. 대부분의 활동은 2011 년이었습니다. 작년에 패치를 추가했으나 argparse 패치의 백 로그가 있습니다.

인수가있는 옵션 뒤에 오는 경우 '--env' 또는 "-s WHATEVER -e COOL STUFF"과 같은 문자열에서 잠재적 인 모호성이 있습니다.

optparse 간단한 왼쪽에서 오른쪽 구문 분석을 수행합니다. 첫 번째 --env은 하나의 인수를 취하는 옵션 플래그이므로, 어떻게 보이는지에 관계없이 다음을 소비합니다. 반면에 argparse은 문자열을 두 번 반복합니다. 먼저 'O'또는 'A'(옵션 플래그 또는 인수)로 분류합니다. 두 번째 루프에서는 변수 nargs 값을 처리하기 위해 패턴 일치와 같은 re을 사용하여 변수를 소비합니다. 이 경우에는 OO, 두 개의 플래그 및 인수가없는 것 같습니다.

argparse을 사용할 때의 해결책은 옵션 문자열에 대해 인수 문자열을 혼동하지 않게하는 것입니다. 여기에 (그리고 버그 문제에) 표시되었습니다 가능성은 다음과 같습니다 : 자체 '--env'으로

--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"' 

는 플래그 (인용하는 경우에도, sys.argv 참조)처럼 보이지만 다른 문자열 다음에 때하지 않습니다. 그러나 "-env one two"['-e','nv one two'],`-e '플래그 다음에 문자열 (또는 더 많은 옵션)이 오는 것으로 해석 될 수 있기 때문에 문제가 있습니다.

--nargs=argparse.PARSER은 다음의 모든 문자열을 인수로 강제로 표시하는데도 사용할 수 있습니다 (argparse). 그러나 인수 목록의 끝에서만 작동합니다.

args_default_to_positional=True 모드를 추가하기 위해 issue9334에 제안 된 패치가 있습니다. 이 모드에서 구문 분석기는 문자열을 정의 된 인수와 명확하게 일치시킬 수있는 경우에만 문자열을 옵션 플래그로 분류합니다. 따라서 '--env --one'의 '--one'은 인수로 분류됩니다. 그러나 '--env --env'의 두 번째 '--env'는 여전히 옵션 플래그로 분류됩니다.


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) 

에 관련된 경우에 확장은 생성

-foo-f 플래그로서 해석되기 때문에 "-foo 한"경우에 실패
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) 

플러스 불특정 엑스트라들. 이는 -fe['-f','-e']으로 해석되는 것과 동일한 동작입니다.

-e 그 플래그의 인수로 해석됩니다 후 나는 nargsREMAINDER에 (하지 PARSER), 모든 것을 변경하는 경우 :

parser.add_argument("-e", "--extra", nargs=argparse.REMAINDER) 

모든 경우에 작동합니다. 값은 목록입니다. 그리고 따옴표는 필요하지 않습니다 : 그것은 플래그처럼 여부를 찾을 지 여부를 다음과 모든 소요를 제외하고

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는 '*'와 같습니다. argparse.PARSER은 '+'와 비슷합니다. positional과 같은 인수가 먼저옵니다. subparsers이 사용하는 nargs입니다. 당신이

+2

대단히 감사합니다.'nargs = argparse.PARSER'는 나를 도왔습니다. – guettli

+0

나는 무엇이 바뀌 었는지 모르지만, 이제는'python Application.py queue -env "-s WHATEVER -e COOL STUFF"가 작동합니다. stand-alone '-foo'(또는 '--foo')가 여전히 플래그로 해석되기 때문에'queue -env "-foo"'는 여전히 오류를 발생시킵니다. apprent 플래그 이후의 공백은 차이를 만듭니다. – hpaulj

관련 문제