【问题标题】:How to implement both positional arguments and flag options in python3 command line with argparse?如何使用argparse在python3命令行中实现位置参数和标志选项?
【发布时间】:2020-04-30 14:45:43
【问题描述】:

我想通过argparse实现一个python3命令行,它支持位置参数和标志选项。

例如:

usage: mycmd [-v] [-h] [-o] text

mycmd text       print text
mycmd -h         show help message and exit
mycmd -v         show version info
mycmd -o text    print text and dump text to file mycmd.txt

这是我的实现:

import argparse

class MyCmd:
  def __init__(self):
    self.parser = argparse.ArgumentParser()
    self.parser.add_argument('text', help='print text')  # mycmd text
    self.parser.add_argument('-v', action='store_true', dest='version', help='show version info') # mycmd -v
    self.parser.add_argument('-o', dest='output', help='print text and dump text to file mycmd.txt')
  def parse(self):
    return self.parser.parse_args()
  def text(self, text):
    print(text)
  def version(self):
    print('version info: mycmd-0.0.1')
  def output(self, text):
    print(text)
    fp = open('mycmd.txt', 'w')
    fp.write(text + '\n')
    fp.close()

if __name__=='__main__':
  mycmd = MyCmd()
  (options, args) = mycmd.parse()
  if options.text is not None:
    mycmd.text(text)
  elif options.version is not None:
    mycmd.version()
  elif options.output is not None:
    mycmd.output(options.output)

当我测试它时:

$ ./mycmd -v

给我错误:

usage: mycmd [-h] [-o OUTPUT]
            [-v]
            text
mycmd: error: the following arguments are required: text

为什么 mycmd 不能消费 mycmd -v

【问题讨论】:

  • 您没有提供text 参数。
  • 使用“-v”并不能阻止它尝试解析所有参数,并在缺少所需参数时引发错误。但是有一个“版本”动作类,它会在进行其余的解析之前打印一个值并退出。

标签: python-3.x argparse


【解决方案1】:

您的原始实现缺少的是在文本处理流程中包含特定子解析的步骤。

这是一个更简化的版本(没有类):

import argparse


def version():
    return 'v0.0.1'

def print_and_save(text, file_path):
    print(text)
    if file_path:
        with open(file_path, 'w') as fp:
            fp.write(text + '\n')
            fp.close()


if __name__=='__main__':
    # Root (rt)
    root_parser = argparse.ArgumentParser()
    root_parser.add_argument('-v', '--version', action='store_true', help='show version info')

    root_sbparsers = root_parser.add_subparsers(help='sub-command help')

    # Adding sub-commands
    text_parser = root_sbparsers.add_parser('process', help='print text')
    text_parser.add_argument('text', type=str, help='text you want to work with')
    text_parser.add_argument('-o', type=str, default=None, help='print text and dump text to file mycmd.txt')

    args = root_parser.parse_args()

    if args.version:
        print(version())
    elif args.text:
        print_and_save(args.text, args.o)

我不知道为什么你必须将它嵌入到整个班级,但这是它的版本:

import argparse

class MyCmd(object):
    def __init__(self):
        # Root (rt)
        self.parser = argparse.ArgumentParser()
        self.parser.add_argument('-v', '--version', action='store_true', help='show version info')

        root_sbparsers = self.parser.add_subparsers(help='sub-command help')

        # Adding sub-commands
        text_parser = root_sbparsers.add_parser('process', help='print text')
        text_parser.add_argument('text', type=str, help='text you want to work with')
        text_parser.add_argument('-o', type=str, default=None, help='print text and dump text to file mycmd.txt')

    def parse(self):
        return self.parser.parse_args()

    def text(self, text):
        print(text)

    def version(self):
        print('version info: mycmd-0.0.1')

    def output(self, text, file_path):
        with open(file_path, 'w') as fp:
            fp.write(text + '\n')
            fp.close()


if __name__=='__main__':
    mycmd = MyCmd()
    args = mycmd.parse()

    if args.version:
        mycmd.version()
    elif args.text:
        mycmd.text(args.text)
        if args.o:
            mycmd.output(args.text, args.o)

【讨论】:

    猜你喜欢
    • 2012-01-29
    • 2023-03-13
    • 2012-01-05
    • 2018-09-17
    • 2012-07-21
    • 1970-01-01
    • 2011-04-29
    • 2021-01-12
    相关资源
    最近更新 更多