object.write()无法正常工作

时间:2018-07-05 13:57:17

标签: python python-3.x for-loop optimization io

我是python的新手。我想读取一个文件并将数据复制到另一个文件。我的代码如下。在下面的代码中,当我在for循环中打开文件时,可以将所有数据写入dst_file中。但是写入dst_file却需要8秒。

for cnt, hex_num in enumerate(hex_data):
    with open(src_file, "r") as src_f, open(dst_file, "a") as dst_f:
        copy_flag = False
        for src_line in src_f:
            if r"SPI_frame_0" in src_line:
                src_line = src_line.replace('SPI_frame_0', 'SPI_frame_' + str(cnt))
                copy_flag = True

            if r"halt" in src_line:
                copy_flag = False

            if copy_flag:
                copy_mid_data += src_line

        updated_data = WriteHexData(copy_mid_data, hex_num, cnt, msb_lsb_flag)
        copy_mid_data = ""
        dst_f.write(updated_data)

为了提高性能,我试图在for循环之外打开文件。但它不能正常工作。它仅在dst_file中写入一次(for循环的一个迭代)。如下所示。

with open(src_file, "r") as src_f, open(dst_file, "a") as dst_f:
    for cnt, hex_num in enumerate(hex_data):
        copy_flag = False
        for src_line in src_f:
            if r"SPI_frame_0" in src_line:
                src_line = src_line.replace('SPI_frame_0', 'SPI_frame_' + str(cnt))
                copy_flag = True

            if r"halt" in src_line:
                copy_flag = False

            if copy_flag:
                copy_mid_data += src_line

        updated_data = WriteHexData(copy_mid_data, hex_num, cnt, msb_lsb_flag)
        copy_mid_data = ""
        dst_f.write(updated_data)

有人可以帮我发现我的错误吗?

1 个答案:

答案 0 :(得分:0)

文件是迭代器。循环遍历它们会逐行读取文件。 直到您结束。然后,当您尝试阅读更多内容时,他们不仅会回到开始。在文件对象上进行新的for循环不会“重置”文件。

在循环中每次都重新打开输入文件,或者显式地找回起点,或者只读取一次文件。您可以使用src_f.seek(0)进行查找,重新打开意味着您需要使用两个with语句(一个语句一次打开输出文件,另一个语句在for循环中处理{{1} }源文件)。

在这种情况下,假设您要一次性建立要写入内存的数据,我将只读取一次输入文件,只保留需要复制的行。

您可以在同一文件对象上使用多个src_f循环,文件位置将相应更改。这使得从一个键串的匹配到另一键串的匹配读取一系列行非常简单。 itertools.takewhile() function使其更容易:

for

请注意,我将from itertools import takewhile # read the correct lines (from SPI_frame_0 to halt) from the source file lines = [] with open(src_file, "r") as src_f: for line in src_f: if r"SPI_frame_0" in line: lines.append(line) # read additional lines until we find 'halt' lines += takewhile(lambda l: 'halt' not in l, src_f) # transform the source lines with a new counter with open(dst_file, "a") as dst_f: for cnt, hex_num in enumerate(hex_data): copy_mid_data = [] for line in lines: if "SPI_frame_0" in line: line = line.replace('SPI_frame_0', 'SPI_frame_{}'.format(cnt)) copy_mid_data.append(line) updated_data = WriteHexData(''.join(copy_mid_data), hex_num, cnt, msb_lsb_flag) dst_f.write(updated_data) 更改为列表,以避免二次字符串复制;一次连接一个字符串列表要高效得多。