2017-04-21 37 views
0

我想创建一个方法,它返回一个列表,该列表将实例的类的内容实例作为参数传递以供参考。列表(实例)中的每个元素都有一个属性(实例变量),它是一个字典,每个元素的内容必须与每个元素不同,问题是,即使正确使用其字典中的正确内容创建实例,当它们被追加到要返回的列表中时,列表中的实例的所有字典(attrs)将获得相同的内容。使用python中的对象列表

这是代码

class ModelManager(): 
def get_subset(self, entity_class, condition_string, persistant): 
    entity_subset=[] 
    entity_attrs={} 
    entity_attrs_list=[] 
    attrs_list=[] 
    record_list=persistant.get_subset(entity_class, condition_string, persistant) 

    i=0 
    for record in record_list: 
     if i==0: 
      for data in record: 
       attrs_list.append(data) 
     elif i>1: 
      j=0 
      for data in record: 
       entity_attrs[attrs_list[j]]=data 
       j=j+1 
      new_instance=entity_class.clone() 
      new_instance.set_attrs(entity_attrs) 
      entity_subset.append(new_instance) 
      print(new_instance.attrs)   #first print 
     i=i+1 

    for entity in entity_subset: 
     print(entity.attrs)      #second print 
    return(entity_subset) 

class Company(Entity): 
def clone(self): 
    company=Company() 
    return company 

class Entity: 
def __init__(self): 
    self.attrs={} 

def set_attrs(self, attrs): 
    self.attrs=attrs 

这就是结果。

MacBook-Pro-de-Hugo:oop01 hvillalobos$ virtual/bin/python3 oop01.py 
{'id': '1', 'razon_social': 'Attractora S.A. de C.V.', 'rfc': 'xxxxxxxx'} 
{'id': '2', 'razon_social': 'Otra empresa sa de cv', 'rfc': ' yyyyyyyy'} 
{'id': '3', 'razon_social': 'Una mas sa de vc', 'rfc': ' zzzzz'} 

{'id': '3', 'razon_social': 'Una mas sa de vc', 'rfc': ' zzzzz'} 
{'id': '3', 'razon_social': 'Una mas sa de vc', 'rfc': ' zzzzz'} 
{'id': '3', 'razon_social': 'Una mas sa de vc', 'rfc': ' zzzzz'} 

有没有人知道为什么列表中的所有元素最后都有相同的内容? 谢谢大家

+0

'self.attrs = attrs'不复制数据。你所有的实例都使用相同的'attrs'字典,因为你对每个实例使用相同的字典来调用'set_attrs'。见https://nedbatchelder.com/text/names.html – user2357112

+2

'self.attrs = attrs.copy()'可以帮助 –

+0

任何改变任何可变对象的引用,将改变其所有引用。 – direprobs

回答

0

由于您对所有实例重用相同的字典,因此您当前的代码无法按照您的方式工作。由于您不断修改该字典的内容,最终的结果是您创建的所有实例都拥有应该属于最后一个的数据。

您可以通过几种方法解决此问题。最简单的方法是将字典的创建移动到循环中。另一种选择是在创建完字典之后为每个实例分配一份字典副本。但我认为最优雅的解决方案是更改代码,以便用数据填充字典,以便同时创建新字典。

尝试更换此代码:

j=0 
for data in record: 
    entity_attrs[attrs_list[j]]=data 
    j=j+1 

与:

entity_attrs = dict(zip(attrs_list, record))