python 遇到的小坑详解编程语言

由于前端资源紧缺,我的后端系统迟迟等不来它的前端,没办法只好自己来写了。从html,js入门学起,然后照着vue.js的官方教程写了几个实例,从github上clone了一个不错的vue.js模版,填充了一个星期。虽然界面有些丑,但是总算是走通了全部的业务,期间被跨域,跳转,cookie等问题折磨得不要不要的。有时间的话,本螺旋手里剑会总结vue.js开发过程中遇到的问题。

言归正传,本周博主基本没碰python代码,只是修复了一个bug,这个bug很有意思。bug描述为:本次请求的返回结果中总是携带着之前请求的结果,重启服务后bug暂时修复,稍后又会出现。第一感觉是数据库缓存问题,但是我们没有对mysql启用特殊的缓存机制,所以不是缓存问题。第二感觉是执行相关的sql操作之后,结果是否commit立即生效,经过排查commit生效了,也不是这个问题。那就只好debug代码了,最后一个定位到了一个方法的传参问题。

展示问题代码的简化版本

#!/usr/bin/python 
# -*- coding: utf-8 -*- 
 
 
class TEST(object): 
    def test(self, info, info_list=[]): 
        info_list.append(info) 
        return info_list 
 
 
if __name__ == '__main__': 
    a = TEST() 
    print a.test(1) 
    print a.test(2) 
    print a.test(3)

相信大部分人和我对输出的预期是一样的,在写代码时,我认为输出结果是

[1] 
[2] 
[3]

但是实际的输出结果是

[1] 
[1, 2] 
[1, 2, 3]

看来bug找到了,之前请求的info都保留在了这次请求的返回结果中。重启服务之后,info_list被重新初始化成[],所以bug短暂的消失了。问题找到了,但是为什么会产生这种问题呢。当我们实例化这个方法时,info_list被初始化为[],之后不会被再次初始化。可以理解为info_list在该方法中是一个全局变量,想修改它的值,只能在调用方法时传入一个新的info_list对其覆盖,也就是说将方法调用修改为a.test(1, [])就不会存在这种问题。并不是所有的数据结构都存在这个问题,只有list、dict这种可变的数据结构才会有这种问题,tuple、string、int等都不存在这个问题。所以说,以后在方法中对list、dict做初始化时建议使用以下风格。

 

#!/usr/bin/python 
# -*- coding: utf-8 -*- 
 
 
class TEST(object): 
    def test(self, info, info_list=None): 
        if info_list is None: 
            info_list = [] 
        info_list.append(info) 
        return info_list 
 
 
if __name__ == '__main__': 
    a = TEST() 
    print a.test(1) 
    print a.test(2) 
    print a.test(3)

 

输出结果符合预期

 

 

[1] 
[2] 
[3]

 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/12482.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论