12

When writing text-oriented command line programs in Python, I often want to read either all the files passed on the command line, or (XOR) standard input (like Unix cat does, or Perl's <>). So, I say

if len(args) == 0:  # result from optparse
    input = sys.stdin
else:
    input = itertools.chain(*(open(a) for a in args))

Is this the Pythonic way of doing this, or did my miss some part of the library?

2
  • See stackoverflow.com/questions/1450393/… Commented Apr 15, 2011 at 11:25
  • It's definitely worth following this link if you need more in-depth responses. There's a caveat for Python 2, for example. Commented Jun 6, 2014 at 23:30

2 Answers 2

15

You need fileinput.

A standard use case is:

import fileinput
for line in fileinput.input():
  process(line)
Sign up to request clarification or add additional context in comments.

3 Comments

This is fine if you want to read the file line by line, but if you just want the whole contents of the file in a variable (the equivalent of open("", 'r').read()) there is no built-in way to do that with the fileinput stdlib module. Unless I'm mistaken in reading the docs.
@tehwalrus I worked around that with allText="" before the for loop, and allText += line in it.
You're right about the absence of a read() method. However, for concatenating lines, adding up lines is officially not recommended. It is much more efficient to collect them in a list and then joining them with "".join(lines)—this is the officially recommended method.
2

In Python 3, argparse handles filetype objects very nicely. It's an extremely powerful module and the docs come with many examples, so it's easy to quickly write the code you want. (How Pythonic!)

You may also benefit from this StackOverflow question about using argparse to optionally read from stdin.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.