HAOYANG MI
HAOYANG MI

Reputation: 151

python try...except in handling argument from user input

my python file would read two files from command line using argparse. I want to use 'try...except...' to handle incorrect user input, like non-exist file and incorrect command: for example, I use '-f' to open file, then '-g' is incorrect command.

my codes are:

> parser = argparse.ArgumentParser(description = "Handle with input 
files")
parser.add_argument('-m', dest = "model", type=argparse.FileType('r'))
parser.add_argument('-t', dest = "test", type=argparse.FileType('r'))
parser.add_argument('-d', dest = "permute",type=argparse.FileType('r'))
args = parser.parse_args()

# Parse file names from command line

model_file = open(args.model.name)
test_file = open(args.test.name)
decoy_file = open(args.permute.name)

I try to implement 'try...except' in my code but failed. Here is what I did:

> parser = argparse.ArgumentParser(description = "Handle with input 
files")
parser.add_argument('-m', dest = "model", type=argparse.FileType('r'))
parser.add_argument('-t', dest = "test", type=argparse.FileType('r'))
parser.add_argument('-d', dest = "permute",type=argparse.FileType('r'))
args = parser.parse_args()

# Parse file names from command line
try:
model_file = open(args.model.name)
test_file = open(args.test.name)
decoy_file = open(args.permute.name)
except IOError:
print('Wrong file name')

Upvotes: 0

Views: 2374

Answers (3)

hpaulj
hpaulj

Reputation: 231375

If you don't want the parser to catch and exit bad files, open the files yourself. Just ask the parser for names, not open files.

parser = argparse.ArgumentParser(description = "Handle with input files")
parser.add_argument('-m', dest = "model")    # no type
parser.add_argument('-t', dest = "test")
parser.add_argument('-d', dest = "permute")
args = parser.parse_args()
# print(args)   # good idea when debugging

# Open file names from command line
try:
    model_file = open(args.model)
    test_file = open(args.test)
    decoy_file = open(args.permute)
except IOError:
    print('Wrong file name')

Upvotes: 0

jia Jimmy
jia Jimmy

Reputation: 1848

Firstly the error happend at args = parser.parse_args() when it parse your command param.

As we can see from argparse's origin code:

    ...
    def parse_args(self, args=None, namespace=None):
        args, argv = self.parse_known_args(args, namespace)
        if argv:
            msg = _('unrecognized arguments: %s')
            self.error(msg % ' '.join(argv))
        return args
    ...
    def error(self, message):
        """error(message: string)

        Prints a usage message incorporating the message to stderr and
        exits.

        If you override this in a subclass, it should not return -- it
        should either exit or raise an exception.
        """
        self.print_usage(_sys.stderr)
        args = {'prog': self.prog, 'message': message}
        self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
        # exit here ,that's why can not catch the exception

So when you input incorrectly, like what you mentioned above, like non-exist file or incorrect command , it will call error function in the end, and exit the thread, that's why you cannot catch a exception by try .. except synax.

If you want to catch the exception, you can inherit the main class ArgumentParser, and rewrite the method error. you can take my codes as reference:


import argparse
import sys as _sys
from argparse import ArgumentParser


class ArgumentParserSub(ArgumentParser):
    def error(self, message):
        self.print_usage(_sys.stderr)
        args = {'prog': self.prog, 'message': message}
        raise Exception(('error: %(message)s\n') % args)


parser = ArgumentParserSub(description = "Handle with input files")
parser.add_argument('-m', dest = "model", type=argparse.FileType('r'))
parser.add_argument('-t', dest = "test", type=argparse.FileType('r'))
parser.add_argument('-d', dest = "permute",type=argparse.FileType('r'))

try:
    args = parser.parse_args()
    # Parse file names from command line
    model_file = open(args.model.name)
    test_file = open(args.test.name)
    decoy_file = open(args.permute.name)

except Exception as e:
    print(e)
    print('Wrong file name')

Upvotes: 0

Aidan H
Aidan H

Reputation: 122

I would suggest adding something like this to make sure all arguments are there. Also argparse.FileType('r') will already open the file (meaning you can do something like args.model.readlines()).

if not all([args.model, args.test, args.permute]):
    print("All Arguments are required")
    exit(1)

Upvotes: 1

Related Questions