AttributeError:FileInput实例没有属性'__exit__'

Jus*_*bie 15 python

我试图从多个输入文件中读取并将每个文件中的第二行作为表格彼此相邻打印

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 
Run Code Online (Sandbox Code Playgroud)

但我得到一个"AttributeError:FileInput实例没有属性' __exit__'"

Eri*_*elt 31

问题是,从python 2.7.10开始,fileinput模块不支持用作上下文管理器,即with语句,因此您必须自己处理关闭序列.以下应该有效:

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

for line in f:
    proc(line)

f.close()
Run Code Online (Sandbox Code Playgroud)

请注意,在最新版本的python 3中,您可以将此模块用作上下文管理器.


对于问题的第二部分,假设每个文件使用相同数量的表单数据行进行类似格式化xxxxxx & xxxxx,可以从每个数据的第二列创建数据表,如下所示:

从空列表开始是一个表,其中行将是每个文件中第二列条目的列表:

table = []
Run Code Online (Sandbox Code Playgroud)

现在迭代fileinput序列中的所有行,使用fileinput.isfirstline()以检查我们是否在新文件并创建一个新行:

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()                      
Run Code Online (Sandbox Code Playgroud)

现在table将转换您真正想要的内容,即每行包含每个文件的给定行的第二列条目.要转置列表,可以使用zip然后循环遍历转置表的行,使用join字符串方法使用逗号分隔符(或任何您想要的分隔符)打印每一行:

for row in zip(*table):
    print(', '.join(row))                             
Run Code Online (Sandbox Code Playgroud)

  • @Dannnno fileinput只是迭代序列中的每个文件,只有在调用`next()`时才会实际打开文件,如果到达前一个文件的末尾并且还有剩下的文件.`close()`只调用`nextfile()`来关闭当前文件(如果有一个打开)并前进到序列中的下一个文件,而不实际打开它. (2认同)