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

Reading binary file to a list of structs, but deepcopy overwrites first structs

我正在将一个二进制文件读入 class 个实例的列表中。我有一个循环,可以将文件中的数据读取到一个实例中。当实例填满后,我将实例追加到列表中并再次开始读取。

除了实例的一个元素是 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. groundtruthfile 实例的 rect 属性(我只是把 this 放在这里...)是 Rect class 本身 ,不是那个 class 的一个实例 - 你应该这样做:

    self.rect = Rect()  # note parentheses
    

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

  2. 行:

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

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

    g = groundtruthfile()
    

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

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


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

for _ in range(length[0]):

比:

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