Python 2.7 如何在使用类()时显示argparse中所有子parser的帮助

Python 2.7 如何在使用类()时显示argparse中所有子parser的帮助,python-2.7,command-line-arguments,argparse,Python 2.7,Command Line Arguments,Argparse,使用argparse和cmd行非常新。我已经开始构建一个解析器,允许前端用户通过cmd终端输入数据。解析器正在调用我创建的API()类(创建SQLALCHEMY会话等),示例如下: class API(object): def __init__(self): # all the session / engine config here def create_user(self, username, password, firstname, lastname, e

使用argparse和cmd行非常新。我已经开始构建一个解析器,允许前端用户通过cmd终端输入数据。解析器正在调用我创建的API()类(创建SQLALCHEMY会话等),示例如下:

class API(object):
    def __init__(self):
        # all the session / engine config here

    def create_user(self, username, password, firstname, lastname, email):
        new_user = User(username, password, firstname, lastname, email)
        self.session.add(new_user)
        self.session.commit()
        print(username, firstname, lastname) 

    def retrieve_user(self, username, firstname, lastname):
       # code here ... etc .
要在CMD文件中实现,请执行以下操作:

def main():

    parser = argparse.ArgumentParser(prog='API_ArgParse', description='Create, Read, Update, and Delete (CRUD) Interface Commands')
    subparsers = parser.add_subparsers(
        title='subcommands', description='valid subcommands', help='additional help')    

    api = API() # calling the API class functions/engine 

    # Create command for 'user' 
    create_parser = subparsers.add_parser('create_user', help='create a user') 
    create_parser.add_argument('username', type=str, help='username of the user')
    create_parser.add_argument('password', type=str, help='password')
    create_parser.add_argument('firstname', type=str, help='first name')
    create_parser.add_argument('lastname', type=str, help='last name')
    create_parser.add_argument('email', type=str, help='email address')
    #args = parser.parse_args() <--EDIT:removed from here and placed on bottom
    api.create_user(args.username, args.password, args.firstname, args.lastname, args.email)       

    # Retrieve command for 'user'
    retrieve_parser = subparsers.add_parser('retrieve_user', help='retrieve a user')
    retrieve_parser.add_argument('username', type=str, help='username')
    retrieve_parser.add_argument('firstname', type=str, help='first name')
    retrieve_parser.add_argument('lastname', type=str, help='last name')
    api.retrieve_user(args.username, args.firstname, args.lastname)
等等

我的问题是终端没有打印新解析器的帮助命令(例如检索解析器、更新解析器等)。我是否必须为每个节创建一个“args=parser.parse_arg()”? 其次,我是否创建了一个“args=create_parser.parse_args()”而不是“parser.parse…”我注意到它们在终端上打印了两个不同的东西


非常感谢您对parse_arg()方法放置位置的任何说明(考虑到API()函数的使用)

通常,在创建
解析器
(包括任何子parser)之后,以及在需要使用结果名称空间(通常称为
args
)之前,调用
parse_args
方法

parser.print\u help()
可以在代码中用于显示相同的帮助消息<代码>检索\u解析器。打印\u帮助()将对子解析器执行相同的操作。显然,这些命令只在
main
中工作,在调试(而不是生产)时更有用

argparse
中没有显示所有子parser的帮助的规定。但是,您可以从我刚才描述的
print\u help
命令构造这样一个函数。可能有这样一个函数的答案(但我不知道什么是好的搜索词)

粗略地说,
main()
可以包括:

 parser.add_argument('--bighelp', action='store_true', help='show help for all subparsers')
 ....
 if args.bighelp:
      parser.print_help()
      subparser1.print_help()
      subparser2.print_help()
      ....
      sys.exit(1)  # if want to quit
可以从解析器中获取子解析器列表,但是维护自己的列表可能更容易、更清晰


我关注的是如何让
解析器
工作,而不是调用
api
的下一步

您需要修改
add_subparsers
,添加
dest
参数

subparsers = parser.add_subparsers(dest='cmd',
    title='subcommands', description='valid subcommands', help='additional help')    
然后,在定义所有子Parser之后,执行以下操作:

# should call cmd since I have stored `.dest` there e.g.`subparsers = parser.add_subparsers(dest='cmd'...`
 args = parser.parse_args()
 if args.cmd in ['create_user']:  # or just == 'create_user'
     api.create_user(args...)
 elif args.cmd in ['retrieve_user']:
     api.retrieve_user(args...)
argparse文档显示了如何通过调用以下命令来简化此过程:

 args.subcmdfunc(args)
请参见“子命令”部分中的最后两个示例:

无论哪种方法,都是从
args
名称空间中找出用户指定的子命令,然后调用正确的
api
方法


请记住,
parser.parse_args()
相当于
parser.parse_args(sys.argv[1:])
。因此,无论您使用什么解析器,无论是主解析器还是子解析器,它都必须准备好处理用户可能给出的所有字符串。它是知道如何处理子解析器名称的主解析器。子parser只需处理其名称后面的字符串。如果给出完整的
argv[1://code>列表,它可能会给出一个错误。因此,通常情况下,您不会为特定的子parser调用
parse_args

我在每个新的“parser”之后调用了“parse_args”方法,但它仍然不会显示在终端上,只显示为“create_user”。因此,我需要为每个子parser调用parse_args方法,还是在所有子parser的最后调用它@hpauljNote添加了调用
api
方法的功能。++I查找了
args.subcmdfunc(args)
,但在argparse文档中没有找到任何内容。我记住了本节中的最后两个示例:当试图从终端调用retrieve_user时,我得到以下错误:
用法:api_argparse[-h]{create_user}。。。API_ArgParse:错误:无效选择:“检索_用户”(从“创建_用户”中选择)
您第一次调用
parse_args
时定义的所有内容都是
create_user
。这就是错误消息告诉您的。在创建所有子parser之后放置
parse_args
。我将
args=parser.parse_args()
放在最末尾(在所有子parser之后),现在我得到了
回溯(最后一次调用):文件“/usr/local/bin/notssdb cmd”,第57行,在main()文件“/usr/local/bin/notssdb cmd”的第25行,在主api.create_user(args.username、args.password、args.firstname、args.lastname、args.email)中,取消绑定LocalError:在赋值之前引用局部变量“args”
,这很有意义,因为args现在定义在底部。我将用适当的标记来反映这一点,以便进行编辑。也许这是一个我应该构建IF/ELIF/ELIF语句的实例,以便解析器遍历命令,直到匹配正确的命令为止。
subparsers = parser.add_subparsers(dest='cmd',
    title='subcommands', description='valid subcommands', help='additional help')    
# should call cmd since I have stored `.dest` there e.g.`subparsers = parser.add_subparsers(dest='cmd'...`
 args = parser.parse_args()
 if args.cmd in ['create_user']:  # or just == 'create_user'
     api.create_user(args...)
 elif args.cmd in ['retrieve_user']:
     api.retrieve_user(args...)
 args.subcmdfunc(args)