来自目录的arparse python参数

时间:2015-08-31 16:14:29

标签: python command-line-arguments argparse positional-operator

我有这样的文件结构:

project/ main_prog.py tools/ script.py md_script/ __init__.py md_script.py

我在工具中搜索本地python模块。在这个例子中它是md_script。我想在我的代码中使用它作为安装的位置参数,但是当我使用它时,我遇到了错误:

./jsh.py md_script
usage: jsh.py [-h] {install,call,list,log,restore} ... [md_script]
jsh.py: error: invalid choice: 'md_script' (choose from 'install', 'call', 'list', 'log', 'restore')
ubuntu14.10上的

python3.4 这是我的代码:

parser = argparse.ArgumentParser(prog='jsh.py',
    description='Some help.', epilog='Example of usage: some help')
subparsers = parser.add_subparsers()
parser_install = subparsers.add_parser('install', help = 'Install new project.')
parser_install.add_argument('install', nargs='?', help = 'Name of project to be installed')
if os.path.isdir(full/path/to/tools/):
   name_arg = next(os.walk(full/path/to/tools))[1]
   tools_arg = parser.add_argument_group('Tools', 'Modules from tools')
   for element in name_arg:
      tools_arg.add_argument(element, nargs='?', help='md_script description')
args = parser.parse_args()
try:
  if not len(sys.argv) > 1:
     parser.print_help()
  elif 'install' in args:
     do_some_stuff
  elif element in args:
     do_some_md_script_stuff
  else:
     parser.print_help()

2 个答案:

答案 0 :(得分:2)

<img id="Image-Maps-Com-image-maps-2015-08-31-103251" src="http://www.image-maps.com/m/private/58808/60863-ue1h8277se3mkfllaet1lledi0_worldmap.png" border="0" width="908" height="494" orgWidth="908" orgHeight="494" usemap="#image-maps-2015-08-31-103251" alt="" /> <map name="image-maps-2015-08-31-103251" id="ImageMapsCom-image-maps-2015-08-31-103251"> <area alt="North America" title="North America" href="http://www.google.com" shape="poly" coords="178,249,117,207,98,156,46,104,121,59,158,61,240,41,396,22" style="outline:none;" target="_blank" onclick="window.open("http://www.google.com");" onmouseover="if(document.images) document.getElementById('Image-Maps-Com-image-maps-2015-08-31-103251').src= 'http://i.imgur.com/B9N2Zbv.png';" onmouseout="if(document.images) document.getElementById('Image-Maps-Com-image-maps-2015-08-31-103251').src= 'http://www.image-maps.com/m/private/58808/60863-ue1h8277se3mkfllaet1lledi0_worldmap.png';" />行显示错误:

usage

您需要使用类似

的内容
usage: jsh.py [-h] {install,call,list,log,restore} ... [md_script]

您指定了子分析符,因此您必须为其指定一个子分析符。

jsh.py install md_script 开始,您似乎还创建了其他未在代码中显示的子代理usagecall等。

您还可以在创建subparser后定义位置参数。这就是list来自的地方。注意制作大量[md_script]位置(包括nargs='?'子解析器的参数)。这可能会让您的用户感到困惑。事实上,它似乎让你感到困惑。请记住,install实际上是一个位置参数(需要1个字符串的参数)。

我建议在创建一个复杂的解析器之前尝试使用更简单的解析器。

因此,根据您的评论和示例,我看到您的目标是让用户为模块命名,因此您的脚本可以通过某种方式或其他方式调用它。对于那些填充这些名称的子分子是有道理的。

我想知道你为什么还要创建一个具有相同名称的可选位置参数:

subparser

这是因为你使用属性的存在作为调用这个subparser的证据吗?

module_pars = subparsers.add_parser(element, help = 'Modules from tools')
module_pars.add_argument(element, nargs='?', help=element+' description')

elif element in args: do_some_md_script_stuff 文档还有其他一些想法。

  

处理子命令的一种特别有效的方法是结合使用add_subparsers()方法和对set_defaults()的调用,以便每个子分析器知道它应该执行哪个Python函数。

  

但是,如果需要检查调用的子分析程序的名称,则add_subparsers()调用的dest关键字参数将起作用:

这些避免了'?'的混乱位置参数,释放你使用subparser参数获取真实信息。

argparse

现在您可以查看:

subparsers = parser.add_subparsers(dest='module')
....
for element in name_arg:
    # module_pars = 'parser_'+element   # this does nothing
    module_pars = subparsers.add_parser(element, help = 'Modules from tools')
    module_pars.set_defaults(func = do_some_md_script_stuff)
    # or module_pars.set_default(element='I am here')
    module_pars.add_argument('real_argument')

if args.module='md_script':
    do_some_md_script_stuff(args)

使用替代if hasattr(args, 'func'): func(args) ,您的原始测试仍应有效:

set_defaults

答案 1 :(得分:0)

我是这样做的。这正是我想要的。

if os.path.isdir(TOOLS_PATH):
   name_arg = next(os.walk(TOOLS_PATH))[1]
   for element in name_arg:
      module_pars = 'parser_'+element
      module_pars = subparsers.add_parser(element, help = 'Modules from tools')
      module_pars.add_argument(element, nargs='?', help=element+' description')

我没有测试它,因为我没有测试模块,但./jsh.py md_script进入elif element in args: print('md_script')并打印字符串。所以它看起来很有效。 感谢所有回复。

编辑:我测试了它。在add_argument中我必须改变nargs ='?' for nargs ='*'来捕获多个参数。 为了从命令行中捕获参数,我使用了这个:

elif args:
   for element in name_arg:
      if element in args:
         element_arg = sys.argv[2:]
         done_cmd,msg = opt_exec_module(element,*element_arg)
         my_logger(done_cmd,msg)

不是很优雅,但它有效。