Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AttributeError: FileInput instance has no attribute '__exit__'

Tags:

python

I am trying to read from multiple input files and print the second row from each file next to each other as a table

import sys
import fileinput

with fileinput.input(files=('cutflow_TTJets_1l.txt ', 'cutflow_TTJets_1l.txt ')) as f:
    for line in f:
        proc(line)



def proc(line):
     parts = line.split("&") # split line into parts
     if  "&" in line:    # if at least 2 parts/columns
         print parts[1] # print column 2 

But I get a "AttributeError: FileInput instance has no attribute '__exit__'"

like image 814
Just_Newbie Avatar asked Jun 14 '15 22:06

Just_Newbie


2 Answers

The problem is that as of python 2.7.10, the fileinput module does not support being used as a context manager, i.e. the with statement, so you have to handle closing the sequence yourself. The following should work:

f = fileinput.input(files=('cutflow_TTJets_1l.txt ', 'cutflow_TTJets_1l.txt '))

for line in f:
    proc(line)

f.close()

Note that in recent versions of python 3, you can use this module as a context manager.


For the second part of the question, assuming that each file is similarly formatted with an equal number of data lines of the form xxxxxx & xxxxx, one can make a table of the data from the second column of each data as follows:

Start with an empty list to be a table where the rows will be lists of second column entries from each file:

table = []

Now iterate over all lines in the fileinput sequence, using the fileinput.isfirstline() to check if we are at a new file and make a new row:

for line in f:
    if fileinput.isfirstline():
        row = []
        table.append(row)
    parts = line.split('&')
    if len(parts) > 1:
        row.append(parts[1].strip())

f.close()                      

Now table will be the transpose of what you really want, which is each row containing the second column entries of a given line of each file. To transpose the list, one can use zip and then loop over rows the transposed table, using the join string method to print each row with a comma separator (or whatever separator you want):

for row in zip(*table):
    print(', '.join(row))                             
like image 95
Eric Appelt Avatar answered Oct 16 '22 06:10

Eric Appelt


If something has open/close methods, use contextlib.closing:

import sys
import fileinput
from contextlib import closing

with closing(fileinput.input(files=('cutflow_TTJets_1l.txt ', 'cutflow_TTJets_1l.txt '))) as f:
    for line in f:
        proc(line)
like image 28
kzh Avatar answered Oct 16 '22 07:10

kzh