代码之家  ›  专栏  ›  技术社区  ›  dot

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

  •  0
  • dot  · 技术社区  · 7 年前

    出身背景

    我正在尝试编写一个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:unhabable type:'list”

    谢谢

    编辑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 回复  |  直到 7 年前
        1
  •  0
  •   Marcus    7 年前

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

        2
  •  0
  •   Paddy    7 年前

    这是个好问题。 试试这个。

    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
    
        3
  •  0
  •   BlackBear    7 年前

    你可以很巧妙地用 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还支持不同的参数类型、验证等。