2017-07-17 7 views
0

私は、とりわけ、ユーザーが引数を使ってロードしてからアクションを実行するためのモジュールを指定できるプログラムを書いています。私はこの内部モジュールに引数を簡単に渡す方法を設定しようとしています。ArgParseのaction='append'を使用して、渡す引数のリストを作成しようとしていました。ここで引用符で囲まれた引数を受け入れるようにargparseを設定する

は私がしかし

parser.add_argument('-M', '--module', 
        help="Module to run on changed files - should be in format MODULE:CLASS\n\ 
          Specified class must have function with the signature run(src, dest)\ 
          and return 0 upon success", 
        required=True) 
parser.add_argument('-A', '--module_args', 
        help="Arg to be passed through to the specified module", 
        action='append', 
        default=[]) 

を使用しています、引数の基本的なレイアウトである - 私は、その後python my_program -M module:class -A "-f filename"でこのプログラムを実行しようとした場合(ここで、私は私のモジュールに-f filenameを通過したいと思います)、それ独自の引数として-fを解析しているようだ(と私はエラーにmy_program: error: argument -A/--module_args: expected one argument

任意のアイデア

+1

'sys.argv'を見てください。引用符でパーサーに伝わるのか、それともシェルで飲み込まれていますか? – hpaulj

答えて

1

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('-M', '--module', 
        help="Module to run on changed files - should be in format MODULE:CLASS\n\ 
          Specified class must have function with the signature run(src, dest)\ 
          and return 0 upon success", 
        ) 
parser.add_argument('-A', '--module_args', 
        help="Arg to be passed through to the specified module", 
        action='append', 
        default=[]) 
import sys 
print(sys.argv) 
print(parser.parse_args()) 

私が手:

1028:~/mypy$ python stack45146728.py -M module:class -A "-f filename" 
['stack45146728.py', '-M', 'module:class', '-A', '-f filename'] 
Namespace(module='module:class', module_args=['-f filename']) 

これは、Linuxのシェルを使用しています。引用された文字列は、sys.argvにあるように1つの文字列のままで、-Aの引数として正しく解釈されます。

引用符なしの場合、-fは別個であり、フラグとして解釈されます。

1028:~/mypy$ python stack45146728.py -M module:class -A -f filename 
['stack45146728.py', '-M', 'module:class', '-A', '-f', 'filename'] 
usage: stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS] 
stack45146728.py: error: argument -A/--module_args: expected one argument 

あなたはwindowsや引用符を同じように処理しない他のいくつかのOS /シェルを使用していますか?私はすでに-k filepathが1つの文字列として渡される述べたように

1032:~/mypy$ python stack45146728.py -A "-k filepath" -A "-t" 
['stack45146728.py', '-A', '-k filepath', '-A', '-t'] 
usage: stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS] 
stack45146728.py: error: argument -A/--module_args: expected one argument 

Argparse `append` not working as expected


あなたがわずかに異なるコマンドラインをについて尋ねました。スペースのために、​​はそれをフラグとして解釈しません。しかし、それは裸の '-t'をフラグとして解釈します。

フラグの代わりに未定義の '-xxx'文字列を引数として解釈する可能性についてバグ/問題がありました。私はそれを見て、何かが生産に入ったかどうかを見なければならないだろう。

文字列がフラグまたは引数として分類される方法の詳細はargparse.ArgumentParser._parse_optionalメソッドにあります。

# if it contains a space, it was meant to be a positional 
    if ' ' in arg_string: 
     return None 

http://bugs.python.org/issue9334argparse does not accept options taking arguments beginning with dash (regression from optparse)が話題に古いものと長いバグ/問題である:それはコメントが含まれています。

+0

(クロス質問)回答ありがとう!これらの引用された引数にスペースを埋めて、この回避策についてユーザーに指示するようにしようとしているようです – wKavey

0

ソリューションは、任意の引数を受け入れることになってしまう - ?例がでありますがargparseの文書here

argparse.REMAINDER残りのコマンドライン引数はすべてリストにまとめられています。これは、他のコマンドラインユーティリティに派遣コマンドラインユーティリティのために一般に有用である:付き

>>> parser = argparse.ArgumentParser(prog='PROG') 
>>> parser.add_argument('--foo') 
>>> parser.add_argument('command') 
>>> parser.add_argument('args', nargs=argparse.REMAINDER) 
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split())) 
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B') 
+0

これは興味深い解決策です - しかし私は、少なくとも私のアプリケーションにとっては、任意のコマンド引数を受け入れない方が良いと信じています。少なくともスペースを使った埋め込みの回避策では、ユーザーは意図的に '-A'引数を使用する必要があります – wKavey

関連する問題