【问题标题】:running python3 script in command line在命令行中运行 python3 脚本
【发布时间】:2019-10-25 03:34:57
【问题描述】:

我在 python 中编写了一个函数,它接受2 lists(具有相同的长度)并返回另一个包含 2 个元素的列表。该函数运行良好,但我试图在command line 中运行python 脚本。为此,我想在 python 中使用argparse 模块。我使用以下命令在 python3 中编写了以下脚本:

python3 text.py a b results

脚本应采用 3 个参数,2 个列表作为输入,1 个列表作为输出。这是脚本:

def fun(a, b):
    a_is_greater = 0
    b_is_greater = 0
    for element_a, element_b in zip(a, b):
        if element_a > element_b:
            a_is_greater += 1
        elif element_a < element_b:
            b_is_greater += 1
    return [a_is_greater, b_is_greater]


def main():
    import argparse
    ap = argparse.ArgumentParser(description="")
    ap.add_argument('--list-type', type=list)
    ap.add_argument('--list-type', type=list)
    ap.add_argument('-o', '--outlist', required=True)

    args = ap.parse_args()

    results = fun(a, b)
    return results

if __name__ == "__main__":
    from signal import signal, SIGPIPE, SIG_DFL
    signal(SIGPIPE, SIG_DFL)

    try:
        main()
    except IOError as e:
        if e.errno != 32:
            raise
    except KeyboardInterrupt as e:
        pass

你知道怎么解决吗?我试过这两个列表:a = [4, 5, 2]b = [3, 5, 4]。脚本中的 fun 函数非常适合这 2 个输入。

【问题讨论】:

    标签: python-3.x command-line argparse


    【解决方案1】:

    这样更好吗?

    python3 text.py --list1 [4,5,2] --list2 [3,5,4] -o result # [1, 1]

    def main():
        import argparse
    
        ap = argparse.ArgumentParser(description="")
        ap.add_argument('--list1', type=list)
        ap.add_argument('--list2', type=list)
        ap.add_argument('-o', '--outlist', required=True)
        args = ap.parse_args()
    
        results = fun(args.list1, args.list2)
        print(results)
        return results
    

    代码:

    def fun(a, b):
        a_is_greater = 0
        b_is_greater = 0
        for element_a, element_b in zip(a, b):
            if element_a > element_b:
                a_is_greater += 1
            elif element_a < element_b:
                b_is_greater += 1
        return [a_is_greater, b_is_greater]
    
    
    def main():
        import argparse
    
        ap = argparse.ArgumentParser(description="")
        ap.add_argument('--list1', type=list)
        ap.add_argument('--list2', type=list)
        ap.add_argument('-o', '--outlist', required=True)
        args = ap.parse_args()
    
        results = fun(args.list1, args.list2)
        print(results)
        return results
    
    if __name__ == "__main__":
        from signal import signal, SIGPIPE, SIG_DFL
        signal(SIGPIPE, SIG_DFL)
    
        try:
            main()
        except IOError as e:
            if e.errno != 32:
                raise
        except KeyboardInterrupt as e:
            pass
    

    【讨论】:

      【解决方案2】:

      使用type=listsys.argvargs 的更正代码显示为:

      1353:~/mypy$ python3 stack56531390.py --list1 [4,5,2] --list2 [3,5,4] -o result
      ['stack56531390.py', '--list1', '[4,5,2]', '--list2', '[3,5,4]', '-o', 'result']
      Namespace(list1=['[', '4', ',', '5', ',', '2', ']'], list2=['[', '3', ',', '5', ',', '4', ']'], outlist='result')
      [1, 1]
      

      请注意,“列表”以字符串形式出现。 list 函数将该字符串拆分为一个字符列表。

      In [607]: list('astring')                                                                              
      Out[607]: ['a', 's', 't', 'r', 'i', 'n', 'g']
      

      fun 适用于这些输入的事实更多是巧合,而不是设计使然。输入与测试不匹配:a = [4, 5, 2]' and 'b = [3, 5, 4]

      看看如果用户在列表中加入空格会发生什么:

      1355:~/mypy$ python3 stack56531390.py --list1 [4, 5, 2] --list2 [3,5,4] -o result
      usage: stack56531390.py [-h] [--list1 LIST1] [--list2 LIST2] -o OUTLIST
      stack56531390.py: error: unrecognized arguments: 5, 2]
      

      或引号将间隔列表保持在一起:

      1357:~/mypy$ python3 stack56531390.py --list1 "[4, 5, 2]" --list2 [3,5,4] -o result
      ['stack56531390.py', '--list1', '[4, 5, 2]', '--list2', '[3,5,4]', '-o', 'result']
      Namespace(list1=['[', '4', ',', ' ', '5', ',', ' ', '2', ']'], list2=['[', '3', ',', '5', ',', '4', ']'], outlist='result')
      [2, 3]
      

      所以虽然type=list 可以工作,但它通常不是一个好的选择。请记住,argparse type 是一个给定字符串的函数;它不是类型或类说明符。

      如果我将两个参数更改为采用 int 类型的 * 输入:

      ap.add_argument('--list1', nargs='*', type=int)
      ap.add_argument('--list2', nargs='*', type=int)
      
      1358:~/mypy$ python3 stack56531390.py --list1 4 5 2  --list2 3 5 4 -o result
      ['stack56531390.py', '--list1', '4', '5', '2', '--list2', '3', '5', '4', '-o', 'result']
      Namespace(list1=[4, 5, 2], list2=[3, 5, 4], outlist='result')
      [1, 1]
      

      现在这两个输入是正常的整数列表,而不是包含括号和逗号的字符列表。比较将是数字的,而不是词法的。

      【讨论】:

        猜你喜欢
        • 2016-11-30
        • 2011-03-10
        • 1970-01-01
        • 2012-05-31
        • 1970-01-01
        • 1970-01-01
        • 2019-06-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多