Python中的可变对象与不可变对象

Python中的可变对象与不可变对象


Python中的对象

在Python中“万物皆对象”。
所有的Python对象都有三个特性:身份,类型和值
- 身份:每个对象都有唯一的身份标识,可以认为是该对象的内存地址。可以通过内建函数 id()来得到。
- 类型:对象的类型决定了对象可以进行什么样的操作,保存什么样的值。可以通过内建函数type()来得到。
- 值:对象表示的数据项。


可变对象与不可变对象

可变对象:列表,字典
不可变对象:int,float,string,元组

可变对象

对于可变对象,其中的值是可以发生改变的,以列表为例:

m = [1, 2]
print id(m)
print m
m += [3]
print id(m)
print m

>>>29556648
[1, 2]
29556648
[1, 2, 3]

我们可以看到,列表m的值被改变了。
但是,如果我们执行下面的代码:

m = [1, 2]
print m
print id(m)

m = m + [3]
print m
print id(m)

>>>[1, 2]
28049320
[1, 2, 3]
28081888

这里我们就会发现,在执行了m = m + [ 3 ]之后,是又进行了一个新对象的创建,而不是对原来对象m的值进行修改。

不可变对象

对于不可变对象,以浮点型举例:

a = 1.0
b = 1.0
print "a id is %ld"%(id(a))
print "b id is %ld"%(id(b))

>>>a id is 20206368
b id is 20206368

在这里我们看到,a和b的id是一样的,所以a和b其实是指向的同一个对象。这里和Python的机制有关,因为浮点型是不可变对象,Python会将这些值很高效的缓存,每次新生成一个同样的对象的时候,会直接将其指向已经缓存的对象,而不是产生一个新的对象。而当我们试图将变量的值改变的时候,就相当于指向一个新的对象:

a = 1.0
print "a is %f\n"%a + "a id is %ld"%(id(a))
a += 2
print "a is %f\n"%a + "a id is %ld"%(id(a))

>>>a is 1.000000
a id is 23745312
a is 3.000000
a id is 23745296

这样的操作,会使得Python在执行的相同的操作时,不需要再进行内存空间的开辟。

对于Python来说,每个对象都会有一个计数器,用来记录指向它的引用次数,如果没有引用指向它,那么这个对象将会被回收。

对象作为参数调用

当一个不可变对象作为参数被调用的时候,不管在被调用的地方进行了什么操作,都不会改变对象原来的值,而是会创建新的对象。

a = 'asd'
print id(a)
def foo(b):
    print id(b)
    b += 'f'
    print id(b)

c = foo(a)
print id(c)
print 'a is %s'%a
print id(a)

>>>29248304
29248304
29221248
1458359060
a is asd
29248304

可以看到,函数foo()以字符串a作为参数进行了调用,在调用时,变量b和a指向的是同一个对象,然后对变量b进行修改之后,b指向的对象就发生了改变。执行函数之后,虽然在函数中对变量的值进行了修改,但是函数执行之后,变量a指向的对象还是没有发生改变的,只是在执行期间生成了新的对象。
当一个可变对象作为参数进行调用的时候,在函数中的修改,会直接改变原来的变量指向对象的值。

list1 = [1, 2, 3]
print id(list1)
def foo1(list2):
    list2 += [4]

foo1(list1)
print list1
print id(list1)

>>>27918248
[1, 2, 3, 4]
27918248

可以看到,在可变对象作为参数进行调用的时候,如果在函数中对调用的变量进行了修改,那么就会影响到原来的对象。

这就提供了一个很好的性质,如果我们在使用API的时候,我们可以将不希望改变的东西定义成一个不可变对象进行调用,对希望改变的定义为可变对象进行调用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值