使用动态类的返回值

时间:2014-06-09 01:11:01

标签: python class oop python-2.7 dynamic

我有一种与我一起工作的文件,其中每一行代表不同的“模型”,每个模型都有某些属性。从文件到文件,这些属性可以改变,所以我写了动态类来读取这些文件。这是 -

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']

两个打印报表不应该打印出相同的内容吗?他们不是,我不明白为什么。

1 个答案:

答案 0 :(得分:-5)

每当你迭代catalog时:

return self.__dict__

已添加到您的young列表中:

young.append(model)

这意味着young包含对同一字典的多个引用,它在循环的每次迭代中被修改(每次调用catalog.next时)。因此,当您随后迭代young时,您会一遍又一遍地看到相同的值。

您可以返回字典的副本:

return self.__dict__.copy()

或创建并返回一个新字典,而不是修改实例的__dict__