问题描述
在python中很容易读取和解析csv文件并逐行处理:
reader = csv.reader(open("my_csv_file.csv"))
for row in reader:
# row is an array or dict
parsed_data = my_data_parser(row)
其中 my_data_parser 是我自己的一段逻辑,用于获取输入数据、解析并执行逻辑。
如果我的解析器失败,我想记录 csv 文件的整个原始行,但似乎从 csv 阅读器中我无法再访问它。
是否可以检索原始原始线数据?
解决方法
您可以使用
访问行行号reader.line_num
但似乎没有直接访问实际行的方法(如 doc)。这是避免在任何步骤将整个文件读入内存的迭代方法:
import csv
class MyException(Exception):
pass
def super_logic(line): # Some silly logic to get test code running
if len(line) != 2 or line[1] != '1':
raise MyException("Invalid value")
print("Process: %s" % line)
class LastLineReader:
def __init__(self,fn ):
self.fid = open(fn)
def __iter__(self):
return self
def __next__(self):
line = self.fid.readline() # Read single line and cache it local object
if len(line) == 0:
raise StopIteration()
self.current_line = line.strip()
return line
reader_with_lines = LastLineReader( "my_csv_file.csv" )
reader = csv.reader( reader_with_lines )
for line in reader:
try:
super_logic(line)
except MyException as e:
print("Got exception: %s at line '%s'" % ( e,reader_with_lines.current_line ))
(已编辑:删除了其他解决方案,因为它们在其他 ppl 帖子中也可见)
,csv.reader()
似乎没有公开它正在迭代的文件对象,但是,您可以使用 reader's line_num
属性来实现您想要的。
例如:
import csv
file = open("my_csv_file.csv")
lines = file.readlines()
reader = csv.reader(lines)
for row in reader:
# row is an array or dict
try:
parsed_data = my_data_parser(row)
except MyDataParserError:
print(f"ERROR in line number {reader.line_num}")
print("Full line:")
print(lines[reader.line_num])
file.close()
替代方案
如果您想避免总是将文件加载到内存中,您可以保留读取文件的初始方式,并且仅在发生错误时才将整个文件读入内存:
import csv
reader = csv.reader(open("my_csv_file.csv"))
for row in reader:
# row is an array or dict
try:
parsed_data = my_data_parser(row)
except MyDataParserError:
# Only read the whole file into memory when an error occurred.
file = open("my_csv_file.csv")
lines = file.readlines()
file.close()
print(f"ERROR in line number {reader.line_num}")
print("Full line:")
print(lines[reader.line_num])
,
作为 reader.line_num 的替代方案
for index,row in enumerate(reader):
print(i + 1,row)