我遇到了一个奇怪的问题。它从尝试在django中循环创建对象开始。我在模型save()上执行了类似的操作
self.history.append(new_status)
现在,我认为自己是指正在评估的当前实例。但是,当在一个循环中(在单个python进程上)运行self.history时,它会从上次评估开始进行缓存。
因此,在示例中:
for i in range(3):
job = Job(...properties, exluding history, as that's done in the save() method)
job.save()
存储在数据库中的作业如下:
job1 - id: 1, history: ['pending']
job2 - id: 2, history: ['pending', 'pending']
job3 - id: 3, history: ['pending', 'pending', 'pending']
... so on
现在,如果django服务器没有重新启动,并且再次调用了此控制器,则将创建作业,从创建的最后一个对象的历史记录开始(因此它将以4个挂起对象开始,然后是下一个5个对象,等等)。
基本上是前X条记录和当前N条记录
我已经能够使用简单的Python进行大量复制:
class Base(object):
id = None
name = None
history = list()
def __init__(self, id=None, name=None):
self.id = id
self.name = name
def save(self, **kwargs):
for arg in kwargs:
self.__setattr__(arg, kwargs.get(arg))
class Queue(Base):
def save(self, **kwargs):
self.history.append({'status': 'test'})
super(Queue, self).save()
items = []
for i in range(5):
items.append(Queue(
id=i,
name=str(i) + '-test'
))
for _ in items:
_.save()
print(_.history)
在调试器中运行时,您会得到:
[{'status': 'test'}]
[{'status': 'test'}, {'status': 'test'}]
[{'status': 'test'}, {'status': 'test'}, {'status': 'test'}]
[{'status': 'test'}, {'status': 'test'}, {'status': 'test'}, {'status': 'test'}]
[{'status': 'test'}, {'status': 'test'}, {'status': 'test'}, {'status': 'test'}, {'status': 'test'}]
我真的无法弄清楚-闻起来像不是python问题,但是对对象/引用在Python中的工作方式缺乏了解。
任何帮助都会很棒!谢谢。
答案 0 :(得分:1)
原因是history
是class variable,因此在所有类实例中它都是相同的变量,因此每次在self.history.append({'status': 'test'})
中调用Queue
时,更改在所有实例的范围内。
我希望history
是一个实例变量,应该在方法内部声明它。
编辑
class Base(object):
id = None
name = None
history = list() # <-------- Class variable, global to all instances.
def __init__(self, id=None, name=None):
self.id = id
self.name = name
self.instance_variable = None # <------- Instance variable, global to all methods of the instance.
local_variable = None # <------ Local variable, local to the method of the instance
def save(self, **kwargs):
for arg in kwargs:
self.__setattr__(arg, kwargs.get(arg))