1 变量引用的概念
以下是ipython中对变量赋值的一些操作。
In [1]: a = 1
In [2]: b = a
In [3]: id(a)
Out[3]: 4328158624
In [4]: id(b)
Out[4]: 4328158624
In [5]: a = 2
In [6]: id(a)
Out[6]: 4328158656
In [7]: id(b)
Out[7]: 4328158624
a = 1这条赋值语句,首先会在内存中的某个地址下把1放进去,然后将a这个变量指向1的地址。
b = a这条赋值语句使得变量b所指向的地址与a相同,因此b = 1。
a = 2,在内存中分配一个2的地址,a指向这个地址。
由于没有对b的指向地址作任何改变,因此b指向的地址依然为2的地址。
2 函数传递实参的引用
def test(num):
print(id(num))
a = 1
print(id(a))
test(a)
以上程序执行的结果为:
显然,函数实参传递的是引用,也就是对于上述程序而言,当test函数执行的时候,创建的变量num指向了a的地址。
3 函数返回值传递引用
def test():
m = "s"
print(id(m))
return m
r = test()
print(id(r))
以上程序执行的结果为:
函数返回的是字符"s"的地址引用,因此r = test()实际上是创建了一个变量r来指向test()返回的引用地址。
4 可变类型的变量引用
列表和字典是可变类型,例如,a = [1, 2, 3]这条赋值语句在内存中为[1, 2, 3]分配了空间,然后变量a指向了一块空间的地址,如果修改列表[1, 2, 3]的内部元素不会改变a指向的内存地址。
因此如果将可变类型传入函数作为实参,在函数内部对可变类型数据的修改也会修改函数外部的变量,因为对可变类型元素的修改并没有涉及地址的更改。
5 哈希
哈希实际上是一个算法,它接受一个不可变类型的数据,返回该数据的特征码。例如输入1,返回1,输入"1",返回的是-9197810262360340589。对于不同的数据,其特征码是唯一的,而可变类型是不可哈希的,由于其数据会发生变化,因此无法返回唯一的特征码。
那么在创建字典的时候,实际上首先是将字典的键哈希得到其特征码后将特征码存如内存,因此字典的键一定是不可变类型的数据。