Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用argparse时使函数可导入_Python_Argparse - Fatal编程技术网

Python 使用argparse时使函数可导入

Python 使用argparse时使函数可导入,python,argparse,Python,Argparse,我有以下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 = subpars

我有以下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

这是迄今为止我发现的最干净的方法:

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))
也许其他人可以找到更好的方法。

使用
args.func(**vars(args))
并不适合需要导入和CLI视图的用例

  • 当用户导入一个函数并调用它时,他们希望得到一个用于进一步处理的返回值(控制台上没有打印任何内容。调用者可以根据获得的结果决定打印)
  • 当他们使用CLI时,他们希望看到控制台上打印的输出和正确的退出代码(根据返回值为0或1)
理想的方法是将parsing/CLI management/sum函数分离为单独的函数,并在解析完成后委托处理(下面是一个示例)

上面的示例还将从原始函数中删除*args、**kwargs,并允许委托人根据命令仅发送函数所需的内容

您可以扩展它以支持多个命令

希望这有帮助

一种解决方案可能涉及类似于
args.func(*vars(args))
的内容。但是,我不知道如何从
vars(args)
中删除
func
def foo(x=0,y=0):
可以通过多种方式调用
foo(1,2)
foo(x=1,y=2)
foo(**adict)
foo(**vars(args))
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()))