对于python对象“保存引用而非其值”这个基本概念之前一直未有深切体会。今天正好遇到一个bug,足以说明问题:
定义了这样一个函数
def CheckoutAdsb(usfuldatar):
rstlist=[]
rowRst = {'taskno': usfuldatar[0], 'flagtype': 'none', 'sourcefile': 'none','taskdesc': 'none'}
mytaskno = str.replace(usfuldatar[0], 'QZ-', '') # 注意QZ开头的处理
# 对于CAO应匹配该项目对应的任务
if str.find(usfuldatar[0], 'CAO') > -1:
……
myreftask = Mainttask.objects.filter(taskno__contains=str.strip(mytaskno))
if myreftask.count() == 1:
myreftaskid=myreftask.first().id
……
myflags=mtskflag.objects.filter(ref_task_id=myreftask.first().id)
for flag in myflags:
rowRst['flagtype'] = flag.spectype
rowRst['taskdesc'] = mytaskrev.taskdesc
rowRst['sourcefile'] = flag.specdesc
rstlist.append(rowRst)
……
return rstlist
测试时发现rstlist中的每个内部值都一样,经过一番折腾发现了问题在红色部分
修改后的代码如下:
for flag in myflags: newrowRst={}#关键之处 newrowRst['taskno'] = usfuldatar[0] newrowRst['flagtype'] = flag.spectype newrowRst['taskdesc'] = mytaskrev.taskdesc newrowRst['sourcefile'] = flag.specdesc rstlist.append(newrowRst)
问题顺利解决。如果我在循环内每次都重新初始化rowRst也可以起到作用。关键就在于领会python变量存储的不是值这个问题。