Python列表条目被最后添加的条目覆盖

时间:2010-03-05 18:40:45

标签: python list append

我有这段代码:

def __parse(self):        
    for line in self.lines:
        r = Record(line)
        self.records[len(self.records):] = [r]
        print self.records[len(self.records)-1].getValue() # Works fine!
    print self.record[0].getValue() # Gives the same as
    print self.record[1].getValue() # as
    # ... and so on ...
    print self.record[len(self.record)-1].getValue()

现在它应该做的是用文本行创建记录。但是当我在for循环完成后访问那些列表时,所有记录都为我调用它们的方法提供相同的结果。当我在附加后的for-loop中访问记录时,它是正确的,所以Record init 不能是错误的。不,我绝对肯定我投入的线路是不同的!有谁知道为什么会这样?帮助将非常感谢!

6 个答案:

答案 0 :(得分:1)

您没有追加self.records;你总是覆盖它。

使用:

self.records.append(r)

代替。

修改:没关系。见Ignacio Vasquez-Abrams的评论。如果没有,我会删除这个答案。

答案 1 :(得分:1)

如果用以下内容替换它仍然会发生:

self.record = [Record(l) for l in self.lines]

修改

Record中的必须错误,因为那里的代码确实有效,即使它让有经验的编码人员在阅读时会哭泣。

答案 2 :(得分:1)

啊,你在共享类命名空间中有可变对象 - 这是一个非常常见的错误概念,当你开始使用python时。将records = []CsvSet的初始化移至其__init__函数中,并将record = {}移至Record __init__函数中。应该如下所示:

class Record:
    def __init__(self,lines):
        self.record = {}
        self.__parse()

class CsvSet:
    def __init__(self,lines):
        self.records = []
        self.__parse()

当您在类区域中声明一个可变变量时,它将在这些类的所有实例之间共享,而不是为每个实例创建。通过将初始化移动到实例方法(在这种情况下为__init__),您将为每个实例创建新的可变存储,这正是您的意图。

答案 3 :(得分:1)

记录类已损坏。您使用类变量(Record.record)而不是实例属性。类变量是所有实例的一个,并且您希望每个实例都有不同的self.record

移动:

record = {}
line = ""

进入构造函数的行(在def __init__(self,line):下缩进)

答案 4 :(得分:0)

Record类坏了,你总是返回同一个对象。

没有看到Record的代码,就无法猜测

也许您使用列表或dict作为__init__的默认参数,并使用getValue()返回。

另一种可能性是getValue()返回一个类属性而不是实例属性

答案 5 :(得分:0)

好的,所以我也会发布Record类的代码以便澄清。

  

班级记录:

record = {}
line = ""

def __init__(self,line):
    self.line = line 
    self.__parse()

def __parse(self):
    fieldnames = ['from','to','value','error']
    fields = self.line.split(',')

    c = 0
    for field in fields:
        self.record[fieldnames[c]] = field.strip()
        c+=1

    self.record['from'] = datetime.datetime.strptime(self.record['from'],"%Y-%m-%d")
    self.record['to'] = datetime.datetime.strptime(self.record['to'],"%Y-%m-%d")
     

class CsvSet:

records = []

def __init__(self,lines):
    self.__parse()

def __parse(self):        
    for line in self.lines:
        self.records.append(Record(line))

CsvSet中的__parse方法现在是它的开头。如果出于调试原因我改变了但结果是一样的。而Ignacio你是对的,我在2周前才开始使用Python ......