我有一种与我一起工作的文件,其中每一行代表不同的“模型”,每个模型都有某些属性。从文件到文件,这些属性可以改变,所以我写了动态类来读取这些文件。这是 -
class readmags:
def __init__(self, fname):
self.data = open(fname, 'r')
# Read header to find the columns in the file
while True:
line = self.data.readline()
line = line.lstrip()
if line[0] == '#':
header = line.replace('#', '')
header = header.split()
break
self.header = header
def next(self):
line = self.data.readline()
if line == "":
self.data.close()
raise StopIteration()
# Read in and assign the attributes of the models
cols = line.split()
for i, name in enumerate(self.header):
self.__dict__[name] = float(cols[i])
return self.__dict__
def __iter__(self):
return self
这似乎完全符合我的要求,然而,它返回的对象的行为让我感到困惑。我喜欢根据属性选择模型,所以如果我尝试,
catalog = readmags(<test_file>)
young = []
for model in catalog:
if model['phase'] != 6.0:
young.append(model)
而且,这也是我所期待的。当我尝试在“年轻”列表中选择属性时会出现问题,然后它会返回相同的值,因为列表中有很多条目。例如,
for blah in young:
print blah['age']
只返回相同的值。我仍然是面向对象编程和编写类的新手,所以我可能会误解从readmags返回给我的内容。如果有人能向我解释发生了什么以及如何做我想做的事,我真的很感激。
编辑以添加要测试的小数据集 -
# age log(Z) mass logl logt logg phase log(weight)
5.5000 -2.4089 0.0800 -3.6100 3.3644 5.3500 0.0000 -0.5591
5.5000 -2.4089 0.0900 -3.2700 3.4219 5.2920 0.0000 -0.3456
5.5000 -2.4089 0.1000 -3.0700 3.4492 5.2510 0.0000 -0.4535
5.5000 -2.4089 0.1100 -2.9300 3.4655 5.2180 0.0000 -0.3965
5.5000 -2.4089 0.1300 -2.7300 3.4852 5.1690 0.0000 -0.4183
5.5000 -2.4089 0.1500 -2.4002 3.5584 5.1938 0.0000 -0.3674
以及测试程序 -
models = readmags(<test_file>)
young = []
for model in models:
if model['age'] == 5.5:
print model['mass']
young.append(model)
for star in young:
print star['mass']
两个打印报表不应该打印出相同的内容吗?他们不是,我不明白为什么。
答案 0 :(得分:-5)
每当你迭代catalog
时:
return self.__dict__
已添加到您的young
列表中:
young.append(model)
这意味着young
包含对同一字典的多个引用,它在循环的每次迭代中被修改(每次调用catalog.next
时)。因此,当您随后迭代young
时,您会一遍又一遍地看到相同的值。
您可以返回字典的副本:
return self.__dict__.copy()
或创建并返回一个新字典,而不是修改实例的__dict__
。