将二进制文件读取到结构列表,但deepcopy会覆盖第一个结构

时间:2015-10-05 15:58:44

标签: python struct deep-copy

我正在将二进制文件读入类实例列表中。我有一个循环,将文件中的数据读入实例。当实例被填满时,我将实例附加到列表并再次开始阅读。

除了实例的一个元素是Rect(即矩形),这是用户定义的类型之外,这种方法很好。即使使用deepcopy,也会覆盖属性。

有一些解决方法,例如没有Rect是用户定义的类型。但是,我可以看到这种情况我会遇到很多,并希望有一个简单的解决方案,允许我在循环中读取嵌套类型。

以下是一些代码:

class Rect:
    def __init__(self):
        self.L = 0

class groundtruthfile:
    def __init__(self):
        self.rect = Rect
        self.ht = int
        self.wt = int
        self.text = ''
        ...

data = []
g = groundtruthfile()
f = open("datafile.dtf", "rb")
length = unpack('i', f.read(4))
for i in range(1,length[0]+1): #length is a tuple
    g.rect.L = unpack('i',f.read(4))[0]
    ...
    data.append(copy.deepcopy(g))

这个结果正是我想要的,除了所有data(i).rect.L都是最后读取的数据的值。

1 个答案:

答案 0 :(得分:4)

这里有两个问题:

  1. rect个实例的groundtruthfile属性(我只是将this放在这里......)是 Rect类本身,而不是该类的实例 - 您应该这样做:

    self.rect = Rect()  # note parentheses
    

    来创建一个实例(类似地,例如self.ht = int将该属性设置为整数类,而不是实例);以及

  2. 该行:

    g.rect.L = unpack('i',f.read(4))[0]
    

    明确修改您一直使用的同一groundtruthfile个实例的属性。你应该移动一行:

    g = groundtruthfile()
    

    循环中,这样您每次都可以创建一个单独的实例,而不是尝试创建副本。

  3. 这只是一个最小的修复 - 例如,为各种__init__方法实际提供参数是有意义的,这样您就可以以更直观的方式创建实例。

    此外,如果你在循环中实际上没有使用 i

    for _ in range(length[0]):
    

    比以下更整洁:

    for i in range(1,length[0]+1):