【问题标题】:How to solve this argparse freeze issue?如何解决这个 argparse 冻结问题?
【发布时间】:2016-08-21 00:52:29
【问题描述】:

我想创建一个使用文件和目录的非常简单的终端菜单,所以我尝试了以下方法:

if __name__ == '__main__':

    p = argparse.ArgumentParser(NAME)

    p.add_argument('-data:', '--input_data', default=sys.stdin)
    p.add_argument('-labels:', '--targets', default=sys.stdin)
    p.add_argument('-input_directory:', '--input', default=sys.stdin)
    p.add_argument('-output_data:', '--output', default=sys.stdout)
    opts = p.parse_args()

    if not any([opts.input, opts.output, opts.targets,opts.input_data]):
        p.print_usage()
        quit()
        print '\npress -h to see the help\n'

    elif any([opts.targets,opts.input_data]):
        print '\ncompleted action\n'

        p.print_usage()
        #Recibe (datos, etiquetas)
        perform_stuff(opts.input_data, opts.targets)
        quit()

#Here is the problem:

    elif any([opts.input, opts.output]):
        print '\ncompleted action\n'
        retrive(opts.input)
        write(opts.output)

请注意,为简单起见,我省略了 perform_stuff(path/in/file, path/out/file)retrive(opts.input)write(opts.output) 实现。问题是唯一有效的命令是:

    if not any([opts.input, opts.output, opts.targets,opts.input_data]):
        p.print_usage()
        quit()
        print '\npress -h to see the help\n'

    elif any([opts.targets,opts.input_data]):
        print '\ncompleted action\n'

        p.print_usage()
        #Recibe (datos, etiquetas)
        perform_stuff(opts.input_data, opts.targets)
        quit()

另一方面,当我尝试运行时:

#Here is the problem:

    elif any([opts.input, opts.output]):
        print '\ncompleted action\n'
        retrive(opts.input)
        write(opts.output)

我的简单程序只是冻结。我是 argparse 的新手,我猜这个问题与 if/else 语句的正确使用有关。因此,我应该如何创建我的简单程序的菜单?

【问题讨论】:

  • 从 argparse 的角度来看,看起来一切正常。您应该尝试调试您的程序卡在哪里。
  • 有没有办法在每个命令之间创建一个更好的流程(即,如果一个函数被调用,做这个工作,然后停止)? @ibizaman
  • 这是一个口味问题,但这已经可以满足您的需求了。我怀疑尽管您不需要调用 quit(),除非它是您的功能之一。无论哪种方式,该程序都不应冻结。您能否发布您在函数中实现的内容、如何调用它以使其冻结以及发生这种情况时看到的输出?
  • 感谢@ibizaman 的帮助,我添加了卡住菜单的功能。

标签: python python-2.7 command-line terminal argparse


【解决方案1】:

在这里,我清理并压缩了您的代码,重点是让 if/else 树正常工作。

在解析器中,我将short options 重写为单个字符。我还将默认设置为None。这使得if 测试更容易。 (如果opts.inputstdin 并且你测试if not opts.input: 应该怎么办?)。

import argparse
def quit():
    import sys
    sys.exit(1)

def perform_stuff(*args):
    print 'stuff', args

def retrive(*args):
    print 'retrieve', args        

if __name__ == '__main__':
    p = argparse.ArgumentParser()
    # single letter `-d` string; use default None
    p.add_argument('-d', '--input_data')
    p.add_argument('-t', '--targets')
    p.add_argument('-i', '--input')
    p.add_argument('-o', '--output')
    opts = p.parse_args()
    print 'opts', opts

    if not any([opts.input, opts.output, opts.targets, opts.input_data]):
        p.print_usage()
        print 'press -h to see the help'
        quit()

    elif any([opts.targets,opts.input_data]):
        perform_stuff(opts.input_data, opts.targets)
        quit()

    elif any([opts.input, opts.output]):
        retrive(opts.input, opts.output)
    else:
        print 'else'

示例运行:

1814:~/mypy$ python stack36877714.py
opts Namespace(input=None, input_data=None, output=None, targets=None)
usage: stack36877714.py [-h] [-d INPUT_DATA] [-t TARGETS] [-i INPUT]
                        [-o OUTPUT]
press -h to see the help
1815:~/mypy$ python stack36877714.py -d input_data
opts Namespace(input=None, input_data='input_data', output=None, targets=None)
stuff ('input_data', None)
1815:~/mypy$ python stack36877714.py -t targets
opts Namespace(input=None, input_data=None, output=None, targets='targets')
stuff (None, 'targets')
1815:~/mypy$ python stack36877714.py -i input
opts Namespace(input='input', input_data=None, output=None, targets=None)
retrieve ('input', None)
1816:~/mypy$ python stack36877714.py -o output
opts Namespace(input=None, input_data=None, output='output', targets=None)
retrieve (None, 'output')

你的函数可以这样写:

def retrieve(in_arg, out_arg):
    if in_arg is None:
        data = sys.stdin.read()
        # cannot open/close stdin
    else:
        with open(in_arg,'r') as f:
            data = f.read()
    if out_arg is None:
        # write to sys.stdout
    else:
        # write to open(out_arg,'w')

【讨论】:

  • 感谢您的帮助,我添加了更多详细信息。
猜你喜欢
  • 1970-01-01
  • 2014-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 2011-06-07
相关资源
最近更新 更多