由於前端資源緊缺,我的後端系統遲遲等不來它的前端,沒辦法只好自己來寫了。從html,js入門學起,然後照著vue.js的官方教程寫了幾個實例,從github上clone了一個不錯的vue.js模版,填充了一個星期。雖然界面有些醜,但是總算是走通了全部的業務,期間被跨域,跳轉,cookie等問題折磨得 ...
由於前端資源緊缺,我的後端系統遲遲等不來它的前端,沒辦法只好自己來寫了。從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]