我有以下CLI程序,该程序将两个数字相加:
import argparse
def foo(args):
print('X + Y:', args.x + args.y)
return args.x + args.y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', type=int, default=1)
foo_parser.add_argument('-y', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(args)
假设现在我希望我的用户也能够导入foo
并使用参数x
和y
直接调用它。即我希望foo
看起来像这样:
def foo(x, y):
print('X + Y:', x + y)
return x + y
我如何适应args.func(args)
来处理这个新的foo
?
答案 0 :(得分:1)
args.func(**vars(args))
的使用并不适合需要导入以及CLI视图的用例
理想的方法是将解析/ CLI管理/求和函数分离为单独的函数,并在解析完成后委托处理(以下是示例示例)
from __future__ import print_function # for python2
import argparse
def mysum(x, y=5):
return x+y
def delegator(input_args):
func_map = {
"mysum" : {
"func" : mysum,
"args": (input_args.get("x"),),
"kwargs" : {
"y" : input_args.get("y")
},
"result_renderer": print
}
}
func_data = func_map.get(input_args.get("action_to_perform"))
func = func_data.get("func")
args = func_data.get("args")
kwargs = func_data.get("kwargs")
renderer = func_data.get("result_renderer")
renderer(func(*args, **kwargs))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="action_to_perform")
foo_parser = subparsers.add_parser('mysum')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=3)
delegator(vars(parser.parse_args()))
上述示例还将从您的原始函数中删除* args,** kwargs,并允许委托者根据命令仅发送该函数所需的内容
您可以扩展它以支持多个命令
希望这会有所帮助!
答案 1 :(得分:0)
这是我到目前为止发现的最干净的方法:
import argparse
def foo(*, x, y, **kwargs):
print('X + Y:', x + y)
return x + y
if __name__ == '__main__':
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
foo_parser = subparsers.add_parser('foo')
foo_parser.add_argument('-x', metavar='PATH', type=int, default=1)
foo_parser.add_argument('-y', metavar='PATH', type=int, default=2)
foo_parser.set_defaults(func=foo)
parser.add_argument('--debug', action='store_true', default=False)
args = parser.parse_args()
args.func(**vars(args))
也许其他人可以找到更好的东西。