我认为最好有自己的为 csv.reader 设计的包装器/迭代器。如果 gcs_file 要支持Iterator协议,则不清楚 next() 应该返回什么以始终适应其使用者。
根据 csv reader doc,它
返回一个读取器对象,它将遍历给定 csvfile 中的行。csvfile 可以是任何支持迭代器协议并在每次调用其 next() 方法时返回一个字符串的对象——文件对象和列表对象都适用。如果 csvfile 是文件对象,则必须在不同的平台上使用 'b' 标志打开它。
它需要来自底层文件的一大块原始字节,不一定是一行。您可以拥有这样的包装器(未经测试):
class CsvIterator(object)
def __init__(self, gcs_file, chunk_size):
self.gcs_file = gcs_file
self.chunk_size = chunk_size
def __iter__(self):
return self
def next(self):
result = self.gcs_file.read(size=self.chunk_size)
if not result:
raise StopIteration()
return result
关键是一次读取一个块,这样当你有一个大文件时,你不会炸毁内存或遇到 urlfetch 超时。
或者更简单。要使用内置的iter :
csv.reader(iter(gcs_file.readline, ''))