简体   繁体   English

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

[英]Python list entries are overridden by last appended entry

I've got this code: 我有以下代码:

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()

Now what it should do is making records out of lines of text. 现在,它应该做的是用文本行记录。 But when I access those list after the for-loop has completed all records give the same results for methods I call on them. 但是,当我在for循环完成之后访问这些列表时,所有记录都会为我调用它们的方法提供相同的结果。 When I access a record within the for-loop right after it was appended it's the right one so the Record init can't be fault. 在追加后立即在for循环中访问记录时,它是正确的记录,因此Record 初始化不会出错。 No, it's absolutely sure that the lines I put in are different! 不,绝对可以确保我输入的行是不同的! Has anyone an idea why this happens? 有谁知道为什么会这样? Help would be very appreciated! 帮助将不胜感激!

You aren't appending to self.records ; 您无需追加self.records you are always overwriting it. 您总是会覆盖它。

Use: 采用:

self.records.append(r)

instead. 代替。

Edit : Never mind. 编辑 :没关系。 See Ignacio Vasquez-Abrams's comment. 请参阅Ignacio Vasquez-Abrams的评论。 I would delete this answer if not for that. 如果不是那样的话,我会删除这个答案。

Does it still happen if you replace it with the following: 如果将其替换为以下内容,它是否还会发生:

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

EDIT: 编辑:

Something must be wrong in Record since the code there does work, even if it makes experienced coders weep when they read it. 由于“ Record的代码确实起作用,所以即使在“ Record某些地方也一定是错误的,即使它使有经验的编码人员在阅读时也会哭泣。

Ahue, you have mutable objects in the shared class namespace -- a very common misconception when starting out with python. 嗯,您在共享类名称空间中具有可变对象-从python开始时,这是一种非常常见的误解。 Move the initialization of records = [] in CsvSet into its __init__ function, and move record = {} into Record __init__ function. CsvSetrecords = []CsvSet移到其__init__函数中,然后将record = {}移到Record __init__函数中。 Should look like the following: 应如下所示:

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

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

When you declare a mutable variable in the class area, it is shared among all instances of those classes, not created for each instance. 在类区域中声明可变变量时,该变量在这些类的所有实例之间共享,而不是为每个实例创建。 By moving the initialization into an instance method ( __init__ in this case), you are creating new mutable stores for each instance, which is what you intended. 通过将初始化移动到实例方法(在本例中为__init__ )中,您正在为每个实例创建新的可变存储,这正是您的预期。

Record class is broken. 记录类已损坏。 You use a class variable (Record.record) instead of an instance attribute. 您使用类变量(Record.record)而不是实例属性。 Class variable is one for all instances and you want different self.record for each instance. 类变量对于所有实例都是一个,并且您希望每个实例具有不同的self.record

Move the: 移动:

record = {}
line = ""

lines into the constructor (indented under def __init__(self,line): ) 行到构造函数中(缩进def __init__(self,line):

The Record class is broken, you are always returning the same object. Record类已损坏,您总是返回相同的对象。

Without seeing the code for Record it's impossible to guess 如果没有看到Record的代码,就无法猜测

Perhaps you are using a list or a dict as default parameter to __init__ and returning that with getValue() . 也许您使用列表或字典作为__init__默认参数,并使用getValue()返回它。

Another possibility is that getValue() is returning a class attribute rather than an instance attribute 另一种可能性是getValue()返回的是类属性而不是实例属性

Ok, so I'll post the code for the Record class for clarification, too. 好的,我也将发布Record类的代码以进行澄清。

class 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: CsvSet类:

 records = [] def __init__(self,lines): self.__parse() def __parse(self): for line in self.lines: self.records.append(Record(line)) 

The __parse method in CsvSet is now how it was in the beginning. 现在,CsvSet中的__parse方法是刚开始时的样子。 I changed if for debugging reasons but the result is the same. 如果出于调试原因而更改,但结果相同。 And Ignacio you're right, I startet with Python only 2 weeks ago... 伊格纳西奥(Ignacio),您是对的,我仅在2周前开始使用Python入门...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 更改列表中倒数第二个条目会更改所有先前的条目 - Changing second-to-last entry in list changes all preceding entries while循环中仅将最后一项追加到列表中(Python) - Only the last item is being appended to a list in a while loop (Python) Python:字典存储列表仅在每次迭代中都是最后一个附加值 - Python: List of dictionary stores only last appended value in every iteration python:确定列表的所有条目是否在嵌套列表的条目内 - python: determine if all entries of a list are within entry of a nested list Python string.join ( list ) 最后一个带有“and”的条目 - Python string.join ( list ) last entry with "and" 如何将 Tkinter 条目从条目框中输入到 Python 列表中 - How to Make Tkinter Entries from An Entry Box into A Python List 按python中条目名称中包含的时间戳对列表中的条目进行排序 - Sort entries in list by timestamp included in names of the entry in python python列表未附加 - python list not getting appended 当平均值高于另一个列表中的相同条目时,将列表中的无替换为最后 3 个非无条目的平均值 - Replace None in list with average of last 3 non-None entries when the average is above the same entry in another list Python-tkinter:对于应该从数组收集条目并传递到文本框的循环,仅传递最后一个条目 - Python-tkinter: For loop supposed to collect entries from an array and pass to text box, only passes last entry
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM