78
votes

I want to open file for reading using argparse. In cmd it must look like: my_program.py /filepath

That's my try:

parser = argparse.ArgumentParser()
parser.add_argument('file', type = file)
args = parser.parse_args()
6
And it did what, exactly? - Ry-♦
What is your problem currently? - justhalf
Running this i have error: parser.add_argument('file', type = file) NameError: name 'file' is not defined I don't exaclty understand how argparse work... - nuT707
type = fnc works if fnc is a function that takes a string, and returns a desired object, or raises an error. There isn't a file function in Python. type=open does work since there is a Python function open(filename)'. argparse provides a better function, argparse.FileType()` (actually a function constructor). But a simple string argument as in wims answer is a better starting place. - hpaulj
type=file does work in Python2.7 (and earlier). But in Python3, file has been removed. stackoverflow.com/questions/112970/… - hpaulj

6 Answers

82
votes

The type of the argument should be string (which is default anyway). So make it like this:

parser = argparse.ArgumentParser()
parser.add_argument('filename')
args = parser.parse_args()
with open(args.filename) as file:
  # do stuff here
208
votes

Take a look at the documentation: https://docs.python.org/3/library/argparse.html#type

import argparse

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

print(args.file.readlines())
30
votes

In order to have the file closed gracefully, you can combine argparse.FileType with the "with" statement

# ....

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

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

--- update ---

Oh, @Wernight already said that in comments

17
votes

I'll just add the option to use pathlib:

import argparse, pathlib

parser = argparse.ArgumentParser()
parser.add_argument('file', type=pathlib.Path)
args = parser.parse_args()

with args.file.open('r') as file:
    print(file.read())
0
votes

TL; DR

parser.add_argument(
    '-f', '--file',
    help='JSON input file',
    type=argparse.FileType('r'),
)

Description

Simple command line script to reformat JSON files

reformat-json \
    -f package.json \
    --indent=2 \
    --sort-keys \
    --output=sorted_package.json

can be code in Python as follows

#!/usr/bin/env python3

import argparse, json, sys

EXIT_SUCCESS = 0
EXIT_FAILURE = 1

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        '-f', '--file',
        help='JSON input file',
        type=argparse.FileType('r'),
    )

    parser.add_argument(
        '-i', '--indent',
        help='Non-negative integer indent level',
        type=int
    )

    parser.add_argument(
        '-o', '--output',
        help='Write JSON into output file',
        type=argparse.FileType('w'),
    )

    parser.add_argument(
        '-s', '--sort-keys',
        action='store_true',
        help='Sort output JSON by keys',
    )

    args = parser.parse_args()

    if not args.file:
        parser.print_usage()
        return sys.exit(EXIT_FAILURE)

    gson = json.dumps(
        json.load(args.file),
        indent=args.indent,
        sort_keys=args.sort_keys
    )

    args.file.close()

    if args.output:
        args.output.write(gson)
        args.output.write('\n')
        args.output.close()
    else:
        print(gson)

    return sys.exit(EXIT_SUCCESS)

if __name__ == '__main__':
    main()
-2
votes

This implementation allows the "file name" parameter to be optional, as well as giving a short description if and when the user enters the -h or --help argument.

parser = argparse.ArgumentParser(description='Foo is a program that does things')
parser.add_argument('filename', nargs='?')
args = parser.parse_args()

if args.filename is not None:
    print('The file name is {}'.format(args.filename))
else:
    print('Oh well ; No args, no problems')