0

For example, if I input "python prog.py create filename", the result should be create a file named "filename". But I don't know how to put "args" into defination of create. Could someone give me some advice ? This is code:

    import argparse
    import sys

    class ExecuteShell(object):

        def create(self, args):

        """create a file"""
        print 'xxxxxxxxxxx', args 

            #return args 

        def list(self, args):

        """ccccccc"""
        print args

            #return args

        def delete(self, args):

        """ddddddd"""
        print 'ddddddd'

            #return args

    class TestShell(object):

       def _find_actions(self, subparsers, actions_module, args):

            for attr in (action for action in dir(actions_module) if not action.startswith('__')):

            callback = getattr(actions_module, attr)

            desc = callback.__doc__ or ''

                subparser = subparsers.add_parser(attr, description=desc, add_help=False)

                subparser.add_argument('-h', '--help', action='help',
                                       help=argparse.SUPPRESS)    
                .......

       def main(self, args):

            parser = argparse.ArgumentParser()

            subparsers = parser.add_subparsers()

            a = ExecuteShell()

            subcommand_parser = self._find_actions(subparsers, a, args)

            (options, args) = parser.parse_known_args(args)

    if __name__ == "__main__":

        a = TestShell()
        a.main(sys.argv[1:])

Thanks a lot!

2
  • Are you mixing tabs and spaces in your source code file? You've mixed them in your example. Could you fix the indentation of your example? Commented Sep 17, 2013 at 3:50
  • 1
    Is this a port of an optparse example? Your use of parse_known_args suggests that. So you are creating subparsers that correspond (in name) to the methods (create, etc). But you don't define any arguments. I'd suggest creating a simpler parser modeled on the set_defaults() example of the sub-commands section of argparse documentation. Use the parser to parse the input, and then look in the returned Namespace for the create command and the file name. Commented Sep 17, 2013 at 16:21

1 Answer 1

1

Within the framework you've outlined, I might implement it like the following program. The key items are:

  • parser.add_subparsers takes a dest argument. This lets you know which subparser was invoked.
  • add the an item to the subparser that collects the filenames (subparser.add_argument('files',...) below)
  • actually invoke the command subroutine (the getattr(a,options.command) ... line)

.

import argparse
import sys

class ExecuteShell(object):
    # This function demonstrates that you can put 
    # methods in ExecuteShell(), if you need to, 
    # without having them appear as command-line commands
    # simply by prepending an underscore.
    def _useful(self):
        """Useful method that ISNT a command."""
        return 3.14159

    def create(self, args):
        """create a file"""
        print 'xxxxxxxxxxx', args 

    def list(self, args):
        """ccccccc"""
        print args

    def delete(self, args):
        """ddddddd"""
        print 'ddddddd'

class TestShell(object):

   def find_actions(self, subparsers, actions_module, args):
        for attr in (action for action in dir(actions_module) if not action.startswith('_')):
            callback = getattr(actions_module, attr)
            desc = callback.__doc__ or ''
            subparser = subparsers.add_parser(attr, description=desc, help=desc)

            # This add_argument describes the positional argument, like so:
            #   'files' -- the result of matching this argument will be
            #              stored in `options.files`
            #   metavar='FILE' -- The help messages will use the word "FILE"
            #                     when describing this argument
            #   nargs='+' -- `narg` describes how many arguments this should
            #                match. The value `+` means "all of them, but at
            #                least one." 
            subparser.add_argument('files', metavar='FILE', nargs='+')

   def main(self, args):
        # setup parser
        parser = argparse.ArgumentParser()
        subparsers = parser.add_subparsers(dest='command')
        a = ExecuteShell()
        subcommand_parser = self.find_actions(subparsers, a, args)

        # Run parser
        args = parser.parse_args(args)

        # Run selected command
        # If we reach this statement, then:
        #    args.command is the command the user chose, 
        #       for example, 'create' or 'list'
        #    args.files is the list of arguments that followed 'create' or 'list'
        #    a is an instance of ExecuteShell
        #    getattr(a, args.command) is the attribute or method of `a`
        #       the name in `args.command`, for example, a.create or a.list
        #    getattr(a, args.command)(args.files) invokes that method,
        #       passing in the list of user arguments
        #    So, this line in effect might call `a.create(['file1', 'file2'])`
        getattr(a, args.command)(args.files)

if __name__ == "__main__":

    a = TestShell()
    a.main(sys.argv[1:])
Sign up to request clarification or add additional context in comments.

2 Comments

First of all, thanks for your help. But I still have some questions, I hope you can help me to solve them. Question 1: What does "metavar='FILE', nargs='+'" mean? Question 2: Could you tell me what the mean of "def _useful(self)", it is not invoked... Thank you !
Asking a question again, "getattr(a, options.command)(options.files)" , how does it works ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.