私はpythonを初めて使用します。現在、アプライアンスでAPI呼び出しを行うスクリプトがあります。機能を拡張し、指定された引数に基づいてさまざまな関数を呼び出したいと思います。スクリプトを呼び出すとき。
現在、私は以下を持っています:
parser = argparse.ArgumentParser()
parser.add_argument("--showtop20", help="list top 20 by app",
action="store_true")
parser.add_argument("--listapps", help="list all available apps",
action="store_true")
args = parser.parse_args()
私もいる
def showtop20():
.....
そして
def listapps():
....
与えられた引数に基づいてどのように関数を呼び出すことができますか?走りたくない
if args.showtop20:
#code here
if args.listapps:
#code here
メインの実行可能ファイルをきれいに整頓した後、さまざまな機能をモジュールに移動したいので。
与えられた引数に応じて1つだけの関数を実行したいように見えるので、オプションの引数(./prog command
または./prog --command1
)ではなく、必須の位置引数./prog --command2
を使用することをお勧めします。
だから、このような何かがそれを行う必要があります:
FUNCTION_MAP = {'top20' : my_top20_func,
'listapps' : my_listapps_func }
parser.add_argument('command', choices=FUNCTION_MAP.keys())
args = parser.parse_args()
func = FUNCTION_MAP[args.command]
func()
この猫をスキニングする方法はたくさんあります。ここに_action='store_const'
_を使用したものがあります(文書化されたサブパーサーの例から着想を得ています):
_p=argparse.ArgumentParser()
p.add_argument('--cmd1', action='store_const', const=lambda:'cmd1', dest='cmd')
p.add_argument('--cmd2', action='store_const', const=lambda:'cmd2', dest='cmd')
args = p.parse_args(['--cmd1'])
# Out[21]: Namespace(cmd=<function <lambda> at 0x9abf994>)
p.parse_args(['--cmd2']).cmd()
# Out[19]: 'cmd2'
p.parse_args(['--cmd1']).cmd()
# Out[20]: 'cmd1'
_
共有dest
を使用すると、各アクションはその関数(const
)を同じネームスペース属性に入れます。関数はargs.cmd()
によって呼び出されます。
また、文書化されたサブパーサーの例のように、これらの関数は、ネームスペースの他の値を使用するように記述できます。
_args = parse_args()
args.cmd(args)
_
比較のために、同等のサブパーサーの場合を次に示します。
_p = argparse.ArgumentParser()
sp = p.add_subparsers(dest='cmdstr')
sp1 = sp.add_parser('cmd1')
sp1.set_defaults(cmd=lambda:'cmd1')
sp2 = sp.add_parser('cmd2')
sp2.set_defaults(cmd=lambda:'cmd2')
p.parse_args(['cmd1']).cmd()
# Out[25]: 'cmd1'
_
ドキュメントに示されているように、サブパーサーを使用すると、コマンドごとに異なるパラメーター引数を定義できます。
そしてもちろん、これらのadd
引数またはパーサーステートメントはすべて、キーを関数とペアにするリストまたは辞書のループで作成できます。
別の重要な考慮事項-どのような使用法とヘルプが必要ですか?さまざまなアプローチにより、非常に異なるヘルプメッセージが生成されます。
関数が「十分に単純」な場合は、type
パラメーターのアドバンテージを取ります https://docs.python.org/2.7/library/argparse.html#type
type =は、単一の文字列引数を取り、変換された値を返す任意の呼び出し可能オブジェクトを取ることができます。
あなたの例では(変換された値が必要ない場合でも):
parser.add_argument("--listapps", help="list all available apps",
type=showtop20,
action="store")
この簡単なスクリプト:
import argparse
def showtop20(dummy):
print "{0}\n".format(dummy) * 5
parser = argparse.ArgumentParser()
parser.add_argument("--listapps", help="list all available apps",
type=showtop20,
action="store")
args = parser.parse_args()
あげる:
# ./test.py --listapps test
test
test
test
test
test
test
少なくともあなたが説明したことから、--showtop20
および--listapps
はオプションよりもサブコマンドのように聞こえます。この場合、サブパーサーを使用して目的の結果を得ることができます。概念実証は次のとおりです。
import argparse
import sys
def showtop20():
print('running showtop20')
def listapps():
print('running listapps')
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# Create a showtop20 subcommand
parser_showtop20 = subparsers.add_parser('showtop20', help='list top 20 by app')
parser_showtop20.set_defaults(func=showtop20)
# Create a listapps subcommand
parser_listapps = subparsers.add_parser('listapps', help='list all available apps')
parser_listapps.set_defaults(func=listapps)
# Print usage message if no args are supplied.
# NOTE: Python 2 will error 'too few arguments' if no subcommand is supplied.
# No such error occurs in Python 3, which makes it feasible to check
# whether a subcommand was provided (displaying a help message if not).
# argparse internals vary significantly over the major versions, so it's
# much easier to just override the args passed to it.
if len(sys.argv) <= 1:
sys.argv.append('--help')
options = parser.parse_args()
# Run the appropriate function (in this case showtop20 or listapps)
options.func()
# If you add command-line options, consider passing them to the function,
# e.g. `options.func(options)`