[英]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. 将CsvSet
的records = []
的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.