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

如何将argparse合并到具有两个参数的python函数中

  •  -2
  • NicoMane  · 技术社区  · 2 年前

    我正试图弄清楚如何将argparse合并到我创建的接受两个参数的python函数中,以便它可以在命令行中执行。

    例如,在下面的这个函数中:

    def function(arg1, arg2):
            print(arg1 * arg2)
    

    如何实现argparse以便能够在命令行中执行以下内容:

    % python3 pythonscript.py function arg1 arg2
    

    我尝试过使用argparse,但我只找到了如何在python脚本上使用它的教程,而没有找到函数。

    2 回复  |  直到 2 年前
        1
  •  1
  •   furas    2 年前

    要运行函数,您必须加载脚本,而这个脚本必须获取参数并使用它来执行具有预期值的预期函数。

    要获取可以使用的参数 sys.argv , argparse 它需要识别函数的名称并运行它 click , google/python-fire , invoke -可以使其更简单,因为他们可以自动识别功能并执行它。

    首先,我以 sys.argv

    import sys
    
    """
    % python3 script.py mul 1 2
    % python3 script.py add 1 2
    """
    
    def mul(arg1, arg2):
        return arg1 * arg2 
    
    def add(arg1, arg2):
        return arg1 + arg2 
    
    # --- main ---
    
    if len(sys.argv) < 4:
        print("Usage: python3 script.py function arg1 arg2")
        exit(1)
        
    name = sys.argv[1]
    val1 = int(sys.argv[2])
    val2 = int(sys.argv[3])
    
    if name == "mul":
        result = mul(val1, val2)
        print(result)
    elif name == "add":
        result = add(val1, val2)
        print(result)
    else:
        print("wrong function's name")
    

    与dictionary(而不是许多if/else)执行函数相同:

    import sys
    
    """
    % python3 script.py mul 1 2
    % python3 script.py add 1 2
    """
    
    def mul(arg1, arg2):
        return arg1 * arg2 
    
    def add(arg1, arg2):
        return arg1 + arg2 
    
    # --- main ---
    
    if len(sys.argv) < 4:
        print("Usage: python3 script.py function arg1 arg2")
        exit(1)
        
    name = sys.argv[1]
    val1 = int(sys.argv[2])
    val2 = int(sys.argv[3])
    
    functions = {
        "mul": mul,
        "add": add,
    }
    
    if name in functions:
        result = functions[name](val1, val2)
        print(result)
    else:
        print("wrong function's name")
    

    和的模拟器 argparse .

    argparse 可以使用允许发送更复杂参数的选项,如跳过参数以使用默认值等,因此它比 sys.argv

    我添加了选项 --debug 显示额外信息

    import argparse
    
    """
    % python3 script.py --help
    % python3 script.py mul 1 2
    % python3 script.py add 1 2
    % python3 script.py -D mul 1 2
    % python3 script.py -D add 1 2
    % python3 script.py --debug mul 1 2
    % python3 script.py --debug add 1 2
    """
    
    def mul(arg1, arg2):
        return arg1 * arg2 
    
    def add(arg1, arg2):
        return arg1 + arg2 
    
    # --- main ---
    
    import argparse
    
    parser = argparse.ArgumentParser()
    
    parser.add_argument('name')
    parser.add_argument('val1')
    parser.add_argument('val2')
    
    parser.add_argument('-D', '--debug', action='store_true', help='[default: %(default)s]')
    
    args = parser.parse_args()
    
    if args.debug:
       print("args:", args)
    
    name = args.name
    val1 = int(args.val1)
    val2 = int(args.val1)
    
    functions = {
        "mul": mul,
        "add": add,
    }
    
    if name in functions:
        if args.debug:
            print("executing:", functions[name], "with", val1, val2)
        result = functions[name](val1, val2)
        print(result)
    else:
        print("wrong function's name")
    

    具有 点击 它可以更简单,但需要添加装饰器。

    #!/usr/bin/env python3
    
    import click
    
    """
    % python3 script.py mul 1 2
    % python3 script.py add 1 2
    """
    
    @click.group()
    def cli():
        pass
        
    @click.command()
    @click.argument('arg1', type=click.INT)
    @click.argument('arg2', type=click.INT)
    def mul(arg1, arg2):
        print(arg1 * arg2)
    
    @click.command()
    @click.argument('arg1', type=click.INT)
    @click.argument('arg2', type=click.INT)
    def add(arg1, arg2):
        print(arg1 + arg2)
    
    cli.add_command(mul)
    cli.add_command(add)
    
    # --- main ---
    
    cli()
    

    与相同 fire 可以更简单

    import fire
    
    """
    % python3 script.py mul 1 2
    % python3 script.py add 1 2
    """
    
    class Calculator:
    
        def mul(self, arg1, arg2):
            return arg1 * arg2
    
        def add(self, arg1, arg2):
            return arg1 + arg2
    
    # --- main ---
    
    fire.Fire(Calculator)
    
        2
  •  0
  •   Luke L    2 年前

    这样做:

    import sys
    
    def function(arg1, arg2):
        return arg1 * arg2
    
    if __name__ == '__main__':
        args = sys.argv[1:]
        function(*args)
    

    但是,无法通过命令行调用python函数对象。只有python文件和脚本或其他可执行文件才能通过命令行执行。在上面的代码中,参数首先由 sys 图书馆的 .argv 变量,它是一个列表(这里不需要使用argparse)。然后论点被分割 [1:] ,删除第一个参数,该参数通常是文件的路径。最后,参数被解压缩并通过行传递到函数中 function(*args) 。所有这些代码都由 if __name__ == '__main__': 检查哪个对于确定该文件是直接执行还是仅导入(在这种情况下,我们不希望执行块)至关重要。