将二进制文件读取到结构列表,但深度复制会覆盖第一个结构
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
全部是上次读取数据的值
你这里有两个问题:
groundtruthfile
实例的 rect
属性(我只是把 this 放在这里...)是 Rect
class 本身 ,不是那个 class 的一个实例 - 你应该这样做:
self.rect = Rect() # note parentheses
创建实例(类似地,例如 self.ht = int
将该属性设置为整数 class,而不是实例);和
行:
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):
我正在将一个二进制文件读入 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
全部是上次读取数据的值
你这里有两个问题:
groundtruthfile
实例的rect
属性(我只是把 this 放在这里...)是Rect
class 本身 ,不是那个 class 的一个实例 - 你应该这样做:self.rect = Rect() # note parentheses
创建实例(类似地,例如
self.ht = int
将该属性设置为整数 class,而不是实例);和行:
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):