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应用开发中不用考虑变量地址与内存回收,但如果对变量赋值的内存情况完全忽视,则很容易产生意外的结果。