2016-12-12 72 views
1

暗示的通常方法来定义一个子分析器argparse子分析器是做其他参数

master_parser = argparse.ArgumentParser() 
subparsers = master_parser.add_subparsers() 
parser = subparsers.add_parser('sub') 
parser.add_argument('--subopt') 

和子分析器将与

command sub --subopt 

叫我采取的是叫号的包转换器。如果我使用通常的子分析器的做法,我会做

convert ext1_to_ext2 file.ext1 file.ext2 --args 

这既是重复且容易出错,因为用户可能会调用

convert ext1_to_ext3 file.ext1 file.ext2 --args 

我更希望的是,子分析器会自动根据确定主解析器所以用户可以使用命令

convert file.ext1 file.ext2 EXTRA 

和​​将确定从子分析器和file.ext2,并呼叫子分析器ext1_to_ext2解析EXTRA。当然EXTRA这里是subparser具体。

我试着为每个转换器使用参数组(add_argument_group),但参数组中的参数不能重叠,并且我得到了所有分析器中混合参数的混乱列表,因此使用子分析器似乎是一种方法。

我试图使用parse_known_args两个位置参数,确定并使用适当的子分析器来解析剩余的参数,但很难为用户提供来自帮助消息的转换器及其参数列表。

有没有办法做到这一点?

+0

你可以使用['parse_known_args'](https://docs.python.org/3.5/library/argparse.html#partial-parsing)吗?这可以让你解析第一部分的参数,自己评估正确的子分析器,然后将剩下的参数传递给适当的子分析器。 – SethMMorton

+0

这是我现在正在采取的方法,但我正在努力如何为用户提供帮助信息。看起来我需要劫持'convert file.ext1 file.ext2 -h'来打印来自另一个解析器的帮助消息,但是我仍然无法列出来自'convert -h'的所有可用转换器(也许'epilog'可以工作)。 – user2283347

+0

您要求的逻辑类型对'argparse'不合理。直接解析'sys.argv'或通过'argparse'获取值作为简单字符串,然后推导出您应该采取的操作。 – hpaulj

回答

1

推测子分析器的使用是非常棘手的,因为它需要在检查以下每个参数时重新实现​​自身使用的很多逻辑。

一个更简单的方法是采用subparser命令,它常常允许您“检查”下面的参数以确保它们使用正确的参数。例如

# This allows a file name ending with any of the given extensions, 
# or allows "file.1" in place of "file.1.jpg" 
def jpeg_file(s): 
    for ext in ("jpg", "jpeg"): 
     if s.endswith(ext) or os.path.exists("%s.%s" % (s, ext)): 
      return s 
    raise argparse.ArgumentTypeError() 

def tiff_file(s): 
    # similar to jpeg_file 

master_parser = argparse.ArgumentParser() 
subparsers = master_parser.add_subparsers() 
jpg_to_tiff_parser = subparsers.add_parser('sub') 
jpg_to_tiff_parser = parse.add_argument('jpg', type=jpg_file) 
jpg_to_tiff_parser = parse.add_argument('tiff', type=tiff_file) 
+0

但是命令行仍然是'convert sub file.jpg file.tiff'。我刚刚有一个美好的想法,如何劫持'sys.argv'?我可以检查'sys.argv [1]'和'sys.argv [2]',在'sys.argv [1]'之前插入适当的子分析器名称,并用所有子分析器调用'master_parser'。 '-h'消息会有点偏离。 – user2283347

+0

虽然前两个位置参数不一定是'sys.argv [1]'和'sys.argv [2]',但这种方法没有明显的问题。 – chepner

0

在我看来,这给了你一点控制权。它正在朝着你所要求的方向前进。只需添加文件扩展名检查您的需求。

#prog.py 
topParser=argparse.ArgumentParser() 

subParsers = topParser.add_subparsers(
    title='SubCommands', 
    description='Use "prog.py <subCommand> (-h | --help)" to learn more about each subcommand', 
    help='I can do stuff') 

subParser1 = subParsers.add_parser('use1', help="Use1 does one thing") 
subParser2 = subParsers.add_parser('use2', help='Use2 does another thing') 

subParser1.add_argument(
    '-f','--first-arg-for-use1', 
    help="A text file", 
    required=True 
    ) 

subParser1.add_argument(
    '-s','--second-arg-for-use1', 
    help="An encoding", 
    required=True 
    ) 

subParser2.add_argument(
    '-f','--first-arg-for-use2', 
    help="An image format", 
    required=True 
    ) 

args = topParser.parse_args() 
print(args) 

如果没有别的,它会显示如何处理不同层的帮助文本。