如何在使用Class()时为argparse中的所有子分析器显示帮助

时间:2015-08-11 17:20:21

标签: 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, 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)

新编辑/添加 OF args = parser.parse_args()使用这两个命令反映下面的注释。

     args = parser.parse_args() 
     print(args)


if __name__ == '__main__':
    main()

依旧......

我的问题是终端没有打印新解析器的帮助命令(例如retrieve_parser,update_parser等)。我是否必须创建一个&#34; args = parser.parse_arg()&#34;每节? 其次,我是否创建了一个&#34; args = create_parser.parse_args()&#34;只是&#34; parser.parse ...&#34;我注意到它们在终端上打印了两种不同的东西。

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

1 个答案:

答案 0 :(得分:2)

通常在创建parse_args(包括任何子分析符)之后,在需要使用生成的命名空间(通常称为parser)之前调用args方法。

retrieve_parser.add_argument('lastname', type=str, help='last name')

args = parser.parse_args()  # <=========

api.retrieve_user(args.username, args.firstname, args.lastname)

parse_args的目的是阅读sys.argv列表(shell /解释器从命令行创建的列表),并使用您使用add_argument创建的规范对其进行“解析”等等。

parser'知道'关于子分析符,并将argv列表传递给适当的名称(由'retrieve_user'等名称选择)。

如果命令行包含-h(或--help),解析器将显示帮助消息并退出。此消息列出了子分析符,但未显示其参数。如果-h跟随一个subparser名称,那么它就是显示帮助的subparser。

python main.py -h     # main help
python main.py retrieve_user -h   # subparser help
您可以在代码中使用

parser.print_help()来显示相同​​的帮助消息。 retrieve_parser.print_help()将对subparser执行相同的操作。显然,这些命令只能在main内使用,并且在调试(非生产)时更有用。

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

粗略地说,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

可以从解析器中获取子分析器列表,但维护自己的列表可能更容易也更清晰。

我专注于如何让parser正常工作,而不是调用api的下一步。

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

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...)

argparse文档显示了如何通过调用来简化:

 args.subcmdfunc(args)

请参阅子命令部分中的最后两个示例:https://docs.python.org/3/library/argparse.html#sub-commands

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

请注意,parser.parse_args()相当于parser.parse_args(sys.argv[1:])。因此,无论您使用哪种解析器,无论是主要的解析器还是其中一个子解析器,它都必须准备好处理您的用户可能提供的所有字符串。它是知道如何处理subparser名称的主解析器。 subparser只需处理其名称后面的字符串。如果给出完整的argv[1:]列表,它可能会给出错误。因此,通常您不会为特定的子分析符调用parse_args