argparse-如何将特定的args与特定的函数关联

时间:2019-01-09 14:15:58

标签: python

背景

我正在尝试编写一个包含以下多个功能的python脚本:

 import sys
 def util1(x, y):
     assert(x is not None)
     assert(y is not None)
     #does something

 def util2(x, y):
     assert(x is not None)
     assert(y is not None)
     #does something

 def util3(x, y):
     assert(x is not None)
     assert(y is not None)
     #does something

我需要能够调用任何方法命令行:

 python3 myscript.py util1 arg1 arg2

 python3 myscript.py util3 arg1 arg2

问题

我不知道获取命令行参数并将其传递给方法的正确方法。我找到了抢取第一个arg的方法...但是我想说一种“将所有arg传递给函数x”的方法。

到目前为止我尝试过的事情

到目前为止,我在脚本的底部添加了以下逻辑:

 if __name__ == '__main__':
     globals()[sys.argv[1]]()

现在,当我尝试运行脚本时,得到以下响应:

 lab-1:/var/www/localhost/htdocs/widgets# python3 myscript.py utils1 1 99999
 Traceback (most recent call last):
 File "myscript.py", line 62, in <module>
    globals()[sys.argv[1]]()
 TypeError: util1() missing 2 required positional arguments: 'x' and 'y'

我也尝试了以下方法:

     globals()[*sys.argv[1:]]()
     globals()[*sys.argv[1]:[2]]()

但这不起作用。我收到类似“ TypeError:无法散列的类型:'列表'

的错误

如果您能指出正确的方向,我将不胜感激。 谢谢。

编辑1

Based on the recommendation here to review a similar post, I changed my logic to include the argparse library.  So now I have the following: 

parser = argparse.ArgumentParser(description='This is the description of my program')
parser.add_argument('-lc','--lower_create', type=int, help='lower range value for util1')
parser.add_argument('-uc','--upper_create', type=int, help='upper range value for util1')
parser.add_argument('-lr','--lower_reserve', type=int, help='lower range value for util3')
parser.add_argument('-ur','--upper_reserve', type=int, help='upper range value for util3')

args = parser.parse_args()
#if __name__ == '__main__':
#    globals()[sys.argv[1]](sys.argv[2], sys.argv[3])

目前尚不清楚我如何将这些参数与特定功能“链接”。 假设我需要-lc和-uc作为util1。我如何建立联系? 然后例如将-lr和-ur与util3相关联? 谢谢

3 个答案:

答案 0 :(得分:0)

在调用函数时,需要将参数传递给该函数。天真的方法是这样的:globals()[sys.argv[1]](sys.argv[2], sys.argv[3]),尽管您可能想做一些额外的检查以确保参数和被调用的函数都存在。

答案 1 :(得分:0)

您可以使用click整齐地进行此操作,例如

@click.command()
@click.argument('x')
@click.argument('y')
def util1(x, y):
     #does something

您还可以使用varargs,因此不必指定每个参数:

@click.command()
@click.argument('args', nargs=-1)
def util2(args):
    #does something, args is a list

Click还支持不同的参数类型,验证等。

答案 2 :(得分:0)

这是一个很好的问题。 尝试这样。

import sys
def util1(x, y):
    print('This is "util1" with the following arguments: "'+x+'" and "'+y+'"')
    #does something
def util2(x, y):
    print('This is "util2" with the following arguments: "'+x+'" and "'+y+'"')
    #does something

def util3(x, y):
    print('This is "util3" with the following arguments: "'+x+'" and "'+y+'"')
    #does something

locals()[sys.argv[1]](sys.argv[2] , sys.argv[3])

然后这样称呼它,对我来说很棒。刚刚在我的测试机上尝试过。

python file.py util1 arg1 arg2