今天在写一个小工具的时候,被python的局部变量坑了一把,可见基础知识没掌握好,出来混的迟早都要换的。做了一个django的小服务,通过请求,调用相关模块对log日志进行解析,通过highcharts把数据以图表的形式显示出来。做的比较粗糙,我对每个请求都实时解析log,把结果用一个数组result的形式返回,刷新页面发现,每个请求的result都是从前一次请求append出来,也就是说每回的结果都会增大,显然是list初始化问题。于是我用了一个init()函数,
result = []
def init():
result = []
def run():
for item in items:
result.append(item)
return result
问题依旧存在没有做初始化处理!因为对于init函数来说,result是新申请的变量,对于run来说,本身函数没有result的声明,所以默认寻找它上一次的result,所以init里面的result和run里面的result完全是两个变量。
最后我用了下面的代码:
result = []
def run():
result=[]
for item in items:
result.append(result)
return result
在每一次请求中调用一次初始化,这样就ok了。如果一定要使用init(),那就要在init()里面使用global,让该函数知道它是一个全局变量,用的是上一层的变量,而不是重新创建一个。
对于局部变量,如果使用list的其他方法,如append(),remove()等等,是可以直接使用,而不声明global。因为list本身就是一个引用,所以使用result.append() result.reserve()是完全可以的,但是如果做了赋值操作 result = [], 解释器会认为你是在新建一个变量,而原来的指针还是存在的,原来的变量没有被改变。
看看下面这个例子:
a = [1,2,3]
def func(arg):
arg = [1]
func(a)
print a
可以看到,a还是[1,2,3],在这里同样是新建一个新的对象,func中的赋值操作无法改变外层的list如果是下面这个例子:a = [1,2,3]
def func(arg):
arg.append(4)
func(a)
print a
或者是:
a = [1,2,3]
def func():
a.append(4)
func()
print a
如果是这两种写法,那a就是[1,2,3,4]
ok,完!