挂钩argparse python中的参数

时间:2015-08-21 21:43:28

标签: python inheritance runtime argparse

我感兴趣的是将一个类中使用argparse解析的额外参数挂钩到另一个类中的另一个方法,该方法已经使用argparse模块解析了很少的参数。

Project 1
def x():
    parser = argparse.ArgumentParser()
    parser.add_argument('--abc')

Project 2
def y():
     parser = argparse.ArgumentParser()
     parser.add_argument('--temp1')
     parser.add_argument('--temp2')

当我运行x()时,我想在参数y()的列表中添加“--abc”参数,它在运行时是“temp1”,“temp2”。继承是最好的方法来相应地定义构造函数吗?有人可以提供一些示例代码段吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

你可以从Django的management commands中激励自己。它们基本上设置如下:

  • 入口点为run_from_argv,调用create_parser,解析命令行,提取已解析的参数并将其提供给execute;
  • create_parser方法创建一个argparse解析器,并使用add_argument预填充所有命令可用的默认选项。然后,此函数调用类的add_arguments方法,该方法将被子类重载;
  • execute方法负责处理与默认选项关联的各种行为。然后它调用handle,它被子类重载以处理add_arguments引入的特定选项。

您的要求并不完全清楚,但我认为在您的情况下,您不需要使用执行方法。我会选择:

import argparse
import sys

class BaseParser:
    def create_parser(self, progname):
        parser = argparse.ArgumentParser(prog=progname)
        parser.add_argument('--temp1')
        parser.add_argument('--temp2')
        self.add_arguments(parser)
        return parser

    def add_arguments(self, parser):
        pass # to be optionnally defined in subclasses

    def parse_command_line(self, argv):
        parser = create_parser(argv[0])
        options = parser.parse_args(argv[1:])
        parsed_options = vars(options)
        self.handle(**parsed_options) # HAS TO be defined in subclasses

class X(BaseParser):
    def add_arguments(self, parser):
        parser.add_argument('--abc')

    def handle(self, **options):
        abc = options['abc']
        temp1 = options['temp1']
        temp2 = options['temp2']
        # do stuff with thoses variables

class Y(BaseParser):
    def handle(self, **options):
        temp1 = options['temp1']
        temp2 = options['temp2']
        # do stuff

x = X()
y = Y()
args = sys.argv
x.parse_command_line(args)
y.parse_command_line(args)

如果X是Y的子类,则可以进一步简化代码。

答案 1 :(得分:0)

argparse实现了parents功能,允许您将一个解析器的参数添加到另一个解析器。查看文档。或者为了适应你的情况:

parser_x = argparse.ArgumentParser(add_help=False)
parser_x.add_argument('--abc')
parser_y = argparse.ArgumentParser(parents=[parser_x])
parser_y.add_argument('--temp1')
parser_y.add_argument('--temp2')
parser_y.print_help()

打印:

usage: ipython [-h] [--abc ABC] [--temp1 TEMP1] [--temp2 TEMP2]    
optional arguments:
  -h, --help     show this help message and exit
  --abc ABC
  --temp1 TEMP1
  --temp2 TEMP2

需要使用add_help=False来避免-h parser_xparser_y获得的x之间发生冲突。

另一种方法是让def x(parser=None): if parser is None: parser = argparse.ArgumentParser() parser.add_argument('--abc') return parser def y(): .... return parser parsery = y() parserx = x(parsery) 将其参数添加到预定义的解析器中:

add_argument

知道 parser = argparse.ArgumentParser() arg1 = parser.add_argument('--abc') 返回对它创建的参数(Action对象)的引用可能也很有用。

arg1

在shell中执行此操作,您会看到 _StoreAction(option_strings=['--abc'], dest='abc', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None) 显示为:

arg1

$.rand = function(arg) { if ($.isArray(arg)) { var lRandValue = arg[$.rand(arg.length)]; if (lRandValue.type !== "photo") return $.rand(arg); return lRandValue; } else if (typeof arg == "number") { return Math.floor(Math.random() * arg); } }; 是一个可以放在列表,词典中的对象。理论上,您甚至可以将其添加到另一个解析器中。这实际上是父母机制的作用(即复制从父母到孩子的行为引用)。