代码之家  ›  专栏  ›  技术社区  ›  vivek patel

object.write()未按预期工作

  •  0
  • vivek patel  · 技术社区  · 6 年前

    我是python新手。我想读取一个文件并将数据复制到另一个文件。我的代码如下。在下面的代码中,当我打开for循环中的文件时,我可以将所有数据写入dst_文件。但写dst_文件需要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 是的。如下所示。

    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 回复  |  直到 6 年前
        1
  •  0
  •   Martijn Pieters    6 年前

    文件是 迭代器 是的。循环读取文件。 直到你走到尽头 是的。当你试图阅读更多的东西时,他们不会回到开始。一个新的 for 循环文件对象不会“重置”文件。

    在循环中每次重新打开输入文件,显式地返回到起始位置,或者只读取一次该文件。你可以找回来 src_f.seek(0) ,重新打开意味着您需要使用两个 with 语句(一个打开输出文件一次,另一个在 对于 循环以处理 src_f 源文件)。

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

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

    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)
    

    注意我变了 copy_mid_data 以避免二次字符串复制;只连接一次字符串列表要有效得多。