python中引用以及可变类型与不可变类型及hashable

python中引用以及可变类型与不可变类型及hashable

标签: python


python中的引用

Python

  • 变量数据 是分开存储的
  • 数据 保存在内存中的一个位置
  • 变量 中保存着数据在内存中的地址
  • 变量记录数据的地址,就叫做 引用
  • 使用 id() 函数可以查看变量中保存数据所在的 内存地址

注意:如果变量已经被定义,当给一个变量赋值的时候(用=符号),本质上是 修改了数据的引用

  • 变量 不再 对之前的数据引用
  • 变量 改为 对新赋值的数据引用

比如下面的例子:

a = 1
print(id(a))
print(id(1))

a就是变量,1就是数据。你会发现两个输出的结果是一样的,代表a和1的地址相同。

如果你在代码下面加入了a = 2那么在输出id(a)则发现和上面的结果不一样了,这就说明了a更换了指向的地址。所以在python中,使用=这个赋值语句是修改了引用的指向。

python中引用以及可变类型与不可变类型及hashable_第1张图片

但是一定要注意是使用的=赋值语句这样才是修改引用位置。

可变类型与不可变类型

在python中数据类型有数值型、字符串型、元组、列表、字典,其中数值型、字符串型、元组都是不可变类型,而列表、字典都是可变类型,那么可变类型和不可变类型有什么区别呢。不可变类型就是一旦数据被定义,那么就不可以修改,比如你定义了a=1,对于1这个数据是不可被修改的,如果你使用赋值语句a=2,那么你修改的是a的引用,把a指向了2,但并不能改变1这个位置的值,所以就叫做不可变类型,而对于可变类型,比如列表,你如果想要改变列表内容,那么可以使用一些方法比如.append对列表里面的数据进行修改。

l = [1,2,3]
print(id(l))
l.append(4)
print(id(l))

上面的例子,虽然l从[1,2,3]变为了[1,2,3,4]但是l的id是没有变的,相当于下面这个图表示:

在这里插入图片描述

注意:上面使用的.append方法,如果你还是使用**赋值(=)**语句,那么对于可变类型也是修改的引用地址,比如把l.append(4)修改为l = [1,2,3,4]你会发现id就不同了。因为内存中又建立了一块存储的[1,2,3,4]

所以对于可变类型与不可变类型来说,通过赋值语句都是修改的指向地址,只是对于可变类型来说,还提供了方法来进行修改内容。

python中函数的参数传递

在python中函数的参数其实传递的就是引用。比如下面这个代码:

def t1(a):
    pass
b = 1
t1(a)

在函数中的a在外面的b其实指向的是一个东西。

  • 如果参数是不可变类型,那么在函数里面只能通过赋值=语句修改,这时在函数里面修改的东西不会影响到函数外面,因为赋值相当于重新指向了。
  • 而如果传入的是可变类型,那么在函数内部既可以通过赋值也可以通过调用方法来修改变量值,如果是赋值,那么同样不会影响到函数外面,如果是通过的调用方法来修改的,那么就会影响到函数外部。

考虑下面的代码:

def t1(a,l1,l2):
    a = 2
    l1 =[]
    l2.append(7)
b = 3;g_l1 = [1,2];g_l2 = [1,2,3]
t1(b,g_l1,g_l2)
print(b,g_l1,g_l2)

可以发现b的值没有修改,因为是不可变类型并且在函数中使用的是赋值语句,所以相当于函数中的a重新指向了,所以不会影响到b。而g_l1同样没被修改,因为虽然g_l1是可变类型,但是由于在函数内部使用的是赋值语句,所以相当于l1也重新指向了,所以对g_l1不会产生影响,但是对于g_l2和l_2来说,由于是可变类型,而l2又是通过方法来修改的,所以会对函数外部的产生影响。

hashable

从一个错误说起TypeError: unhashable type: 'list',可能在初学的时候会遇见这样的问题,这是在对字典定义的时候,我们用可变类型作为了字典的key,因为字典的key是使用哈希算法进行哈希运算,这样就会增大取数据的速度,而对于哈希算法来说,传入的数据一定要是不可变的,因为这样计算的值才会唯一,否则你传入一个可变的,可能这一次经过哈希算法计算的是一个数,而再一次可能就算出来不一样了,所以在对于字典的key只能使用数值型、字符串以及元组作为key。

你可能感兴趣的:(python)