How to Argparse File in Python

In this tutorial, I’ll show you how you can open and read a text file using command line arguments.

First, create a file called names.txt with a list of names.

To open a file using argparse, first, you have to create code that will handle parameters you can enter from the command line.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('filename', type=argparse.FileType('r'))
args = parser.parse_args()

print(args.filename.readlines())

In our case, the parameter that we pass on the command line is the file name, and it looks like this:

python test.py names.txt

Make sure that the Python and text files are in the same directory, otherwise, you have to supply the full path to these files.

If you run this code without a parameter, it will display the following message:

D:>python test.py
usage: test.py [-h] filename
test.py: error: the following arguments are required: filename

Now, let’s try to run this with a file name as an argument.

D:>python test.py names.txt
['Liam\n', 'Noah\n', 'William\n', 'James\n', 'Logan']

All the lines are displayed inside a single line with the newline characters ‘\n’. Let’s modify this, so each line of the text file is displayed as a single line on the console.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('filename', type=argparse.FileType('r'))
args = parser.parse_args()

for file in args.filename:
    print(file.strip())

The strip function inside the loop removes the newline characters.

D:>python test.py names.txt
Liam
Noah
William
James
Logan

Without this function, the names would be displayed with two newline characters each: one from the text file and one from the for loop.

An alternative way to achieve the same result is to replace the for loop with the with keyword and the read function, instead of strip.

with args.filename as file:
    print(file.read())

Check if File Exists

If we use a file name as a parameter, you have to enter the one that exists, otherwise, the program will result in an error message:

D:>python test.py names1.txt
usage: test.py [-h] filename
test.py: error: argument filename: can't open 'names1.txt': [Errno 2] No such file or directory: 'names1.txt'

To deal with it, we have to handle this parameter and check whether the file exists before reading its content. For this task, we are going to import the sys library and the exists function.

Additionally, we have to handle parameters that a user entered.

So, there are 4 options to handle:

  1. The file exists.
  2. The file doesn’t exist.
  3. Too few arguments.
  4. Too many arguments.

The code is going to look like this:

import os.path
import sys

if len(sys.argv) == 2:
    if os.path.exists(sys.argv[1]):
        with open(sys.argv[1]) as file:
            print(file.read())
    else:
        print('No such file')
elif len(sys.argv) < 2:
    print('Too few arguments')
else:
    print('Too many arguments')

The len(sys.argv) checks how many parameters a user entered. 1 is a file name, 2 is a file name and a parameter, 3 is a file name and two parameters, etc.

This is the result of all 4 types of options:

D:>python test.py names.txt
Liam
Noah
William
James
Logan

D:>python test.py names1.txt
No such file

D:>python test.py
Too few arguments

D:>python test.py names.txt animals.txt
Too many arguments

Handling multiple files

Let’s handle multiple files. If a user enters multiple files, all of them should be checked, instead of returning the “Too many arguments” error.

import os.path
import sys

args_num = len(sys.argv)

if args_num > 1:
    for i in range(1, args_num):
        if os.path.exists(sys.argv[i]):
            with open(sys.argv[i]) as file:
                print(file.read())
        else:
            print('No such file')
else:
    print('Too few arguments')

Now, if you run this code, Python will return this result.

D:>python test.py names.txt animals.txt
Liam
Noah
William
James
Logan
dog
cat
pig
elephant

Handling Different File Types

Additionally, we can try to handle different types of files. In this code, we are going to read only text files and return error messages if a person tries to add the wrong type.

import os.path
import sys

args_num = len(sys.argv)

if args_num > 1:
    for i in range(1, args_num):
        if os.path.exists(sys.argv[i]):
            if sys.argv[i].endswith('.txt'):
                with open(sys.argv[i]) as file:
                    print(file.read())
            else:
                print('Wrong file extension')
        else:
            print('No such file')
else:
    print('Too few arguments')

If you run the code, you’ll notice that an existing file with the wrong file extension is going to return a different message than before.

D:>python test.py names.txt animals.txt file.bat nofile.txt
Liam
Noah
William
James
Logan
dog
cat
pig
elephant
Wrong file extension
No such file