1. Python變量
如果把單一值變量稱為一維變量,把可以擴展元素的變量稱為多維變量,則python的變量可以划分如下:
變量維度 |
Python變量 |
說明 |
|
一維 |
數字 |
int(有符號整型) |
數字類型可以做轉換 |
long(長整型[也可以代表八進制和十六進制]) |
|||
float(浮點型) |
|||
complex(復數) |
|||
字符串 |
字符串有豐富的運算符和內嵌函數; 有格式化輸出; |
||
二維 |
列表 |
除了元祖外,列表和字典可以靈活的擴展元素 |
|
元組 |
|||
字典 |
2. Python變量的賦值處理
這里主要分析情況為,將原始變量賦值給新變量后,二者的變化關聯情況,比如:原始變量為varold,新變量varnew = varold,之后varnew發生了變化,那么varold如何變化,二者的地址情況如何?這里給出測試用例:
用例1:
def whole_modify(value_old, value_new): |
測試結果:
value: ('aaa', 38126200) ('aaa', 38126200) ('aaa', 38126200) (9, 4014992) list: (['a', 2], 43066072) (['a', 2], 43066072) (['a', 2], 43066072) ([3, 'b'], 41421080) Dictionary: ({1: 'a', 'b': 2}, 39583440) ({1: 'a', 'b': 2}, 39583440) ({1: 'a', 'b': 2}, 39583440) ({3: 'c'}, 39599104) |
用例1中whole_modify是對新變量的整體修改,即直接用=號將一個全新的數據整體賦值給新變量,從測試情況看,結論是:
不論一維還是二維變量,通過=號整體賦值后,新變量會重新分配內存,值為新賦給的值;原變量保持不變。
用例2:
print("list:") |
測試結果:
list: (['a', 2], 39932832) (['a', 2], 39932832) ([3, 2], 39932832) ([3, 2], 39932832) dictionary: ({1: 'a', 'b': 2}, 40107728) ({1: 'a', 'b': 2}, 40107728) ({1: 'a', 'b': 'newvaluestr'}, 40107728) ({1: 'a', 'b': 'newvaluestr'}, 40107728) |
用例2中,主要是對二維變量內部元素做修改(一維變量無需測試),從測試情況看,結論是:
老二維變量被賦給新二維變量后,對二者任何一個的內部元素修改,二者的地址不會發生改變,但值會同步被修改。
3. 分析
Python的變量賦值(包括傳參,返回參數等場景),與c/c++區別很大,而且很難用一句話概括其用法。上面兩個測試用例主要是從變量類型的角度來區分,具有很強代表性,可以引申到很多場景輔助理解。
很多人將python的變量賦值當做引用看待,這應該是有問題的,比如上面用例1中,很顯然就不是引用,因為新變量地址和值都變化了,而老變量完全保持不變。而c/c++引用的概念是,新老變量地址不變,值同步變化。
用例2中對二維變量做局部修改,會發現新老變量的局部元素的地址和值都同步變化了(變量本身地址不變),這個和引用相同的地方是值同步變化了,不同的是變量地址也同步變化了。
Python的這種處理,應該是基於內存效率的考慮,雖然python應用開發中不用考慮變量地址與內存回收,但如果對變量賦值的內存情況完全忽視,則很容易產生意外的結果。