Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何恢复读取csv文件?_Python_Python 3.x_Csv - Fatal编程技术网

Python 如何恢复读取csv文件?

Python 如何恢复读取csv文件?,python,python-3.x,csv,Python,Python 3.x,Csv,CSV id,name 001,简 002,温基 003,贝利 ... 到目前为止,程序将只读取一次csv。如果重新启动,程序将从第一行读取001。例如,如果程序在002停止读取,那么下一次开始读取将是003?为此,您需要跟踪您到目前为止读取文件的距离,file.tell()可能会派上用场。之后,您可以从这里开始使用file.seek()读取文件。 代码看起来有点像: import csv with open('test.csv', 'r') as f: reader = csv.re

CSV

id,name
001,简
002,温基
003,贝利
...

到目前为止,程序将只读取一次csv。如果重新启动,程序将从第一行读取
001
。例如,如果程序在
002
停止读取,那么下一次开始读取将是
003

为此,您需要跟踪您到目前为止读取文件的距离,
file.tell()
可能会派上用场。之后,您可以从这里开始使用
file.seek()
读取文件。 代码看起来有点像:

import csv

with open('test.csv', 'r') as f:
   reader = csv.reader(f)
   for i in reader:
      print(i)

您可以在代码中实现同样的效果,方法是跟踪上次读取的行数,并重复发布该行数。

在这种情况下,您每次都必须显式保存当前位置,这在计算上可能有点昂贵,但它可以工作,代码如下:

def read_from_position(last_position):
  file = open("file_location")
  file.seek(last_position)
  file.readline() # Do what you want with this
  return file.tell() # this is the updated last position
导入csv
上次def更新(x):
打开('last.txt','w')作为文件:
file.write(str(x))
def get_last():
尝试:
以open('last.txt','r')作为文件:
返回int(file.read().strip())
除:
打开('last.txt','w')作为文件:
file.write('0')
返回0
将open('your_file.txt','r')作为f:
读卡器=csv。读卡器(f)
last=get_last()+1
电流=1
对于我的读者:
如果当前<上次:
电流+=1
持续
印刷品(一)
电流+=1
上次更新(当前)

使用发电机的魔力:

import csv


def update_last(x):
    with open('last.txt', 'w') as file:
        file.write(str(x))


def get_last():
    try:
        with open('last.txt', 'r') as file:
            return int(file.read().strip())
    except:
        with open('last.txt', 'w') as file:
            file.write('0')
            return 0

with open('your_file.txt', 'r') as f:
    reader = csv.reader(f)
    last = get_last() + 1
    current = 1
    for i in reader:
        if current < last:
            current += 1
            continue
        print(i)
        current += 1
        update_last(current)
当您运行复杂的业务逻辑时,生成器将暂停,
然后在准备好下一行时透明地继续。要做到这一点,每次从CSV文件中读取一行时,都需要将当前位置持续保存在另一个文件中,这当然会增加一些处理开销

我认为创建一个与语句相结合的语句将是解决这个问题的一个非常好的方法,并且将允许在一定程度上最小化开销

下面的代码实现了一个用于读取CSV文件的内容管理器,并允许在读取整个文件之前(在
with
语句的上下文中)中断对CSV文件或CSV文件的读取时自动恢复

这是通过创建一个单独的“状态”文件来完成的,以跟踪成功读取的最后一行。如果在读取过程中未发生异常,则会删除此文件,但不会发生异常,如果发生异常,则会保留此文件。因此,下次读取文件时,将检测现有状态文件,并将其用于允许从先前停止的位置开始读取

值得注意的是,由于每个可恢复的CSV读取器是一个单独的对象,因此一次可以创建和使用多个。在读取CSV文件时,每个文件的关联“状态”文件保持打开状态,因此无需在每次更新其内容时重复打开和关闭

def get_rows(infile='test.csv'):
    with open(infile) as f:
        reader = csv.reader(f)
        for row in reader:
            yield row

for id, name in get_rows():
    out = some_complex_business_logic(id, name)
    print(out)
输出:

行:['id','name']
行:['001','jane']
复读
行:['002','winky']
行:['003','beli']
完成

您必须将进度保存到另一个文件中。这意味着将内容写入另一个文件,然后下一步开始比较两个文件?最简单的方法可能是保存您已读的行数,并在下一步开始时跳过该行数。@mrHOT不是重复的。请先读这个问题。
pathlib.Path.write_text
简化了很多内容。并让您的异常处理程序在
get\u last
call
update\u last(0)
-DRY@PaulMcG:python3.5之前没有添加
Path.write_text()
方法,因此不使用它会使此代码与更多版本兼容……除了使用“老式”方法之外,在这种特殊情况下也不会有太多工作(IMO)。(事实上,我有点惊讶,他们甚至懒得添加像
write_text()。这就是说,每次读取一行时打开和关闭
last.txt
文件都会增加很多开销,特别是因为这需要多次调用操作系统来完成(这往往非常昂贵)。我的一个建议是不要硬编码
last.txt
文件名,因为这样做会防止代码一次用于多个CSV文件。此外,当不再需要文件时,还需要额外的代码来删除该文件…
readline()
可能会在后台进行预读和缓冲,从而使
file.tell()
给出的结果不一定与您的读线进度相匹配。
import csv
import os

class ResumableCSVReader:

    def __init__(self, filename):
        self.filename = filename
        self.state_filename = filename + '.state'
        self.csvfile = None
        self.statefile = None

    def __enter__(self):
        self.csvfile = open(self.filename, 'r', newline='')

        try:  # Open and read state file
            with open(self.state_filename, 'r', buffering=1) as statefile:
                self.start_row = int(statefile.read())

        except FileNotFoundError: # No existing state file.
            self.start_row = 0

        self.statefile = open(self.state_filename, 'w', buffering=1)

        return _CSVReaderContext(self)

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.csvfile:
            self.csvfile.close()
        if self.statefile:
            self.statefile.close()
            if not exc_type:  # No exception?
                os.remove(self.state_filename) # Delete state file.


class _CSVReaderContext:

    def __init__(self, resumable):
        self.resumable = resumable
        self.reader = csv.reader(self.resumable.csvfile)

        # Skip to start row.
        for _ in range(self.resumable.start_row):
            next(self.reader)

        self.current_row = self.resumable.start_row

    def __iter__(self):
        return self

    def __next__(self):
        self.current_row += 1
        row = next(self.reader)

        # Update state file.
        self.resumable.statefile.seek(0)
        self.resumable.statefile.write(str(self.current_row)+'\n')

        return row


if __name__ == '__main__':

    csv_filename = 'resumable_data.csv'

    # Read a few rows and raise an exception.
    try:
        with ResumableCSVReader(csv_filename) as resumable:
            for _ in range(2):
                print('row:', next(resumable))

            raise MemoryError('Forced')  # Cause exception.

    except MemoryError:
        pass  # Expected, suppress to allow test to keep running.

    # CSV file is now closed.

    # Resume reading where left-off and continue to end of file.
    print('\nResume reading\n')

    with ResumableCSVReader(csv_filename) as resumable:
        for row in resumable:
            print('row:', row)

    print('\ndone')