python面向对象特性----mutable, immutable, 函数传参

最近在用C语言做一个课程设计的时候没注意到结构体赋值传的只是指针,程序调试了一下午,被整得不要不要的,到晚上才智商爆发突然想到可能是赋值问题,感觉都心累了。
为什么会想到这件事?下面我们会提到python中的变量就像C语言中的指针变量 ,指针无处不在有木有,为什么说像呢,因为还不了解底层实现,不敢百分之百确定哈。

1、 python面向对象的实质

  1. python 的完全面向对象是指内存中的对象,包括函数,基本数据类型在内存中均为对象
  2. 变量不是对象,变量只是指向对象,就相当于C语言中的指针变量
  3. 数据类型有mutable(可变) 和immutable(不可变)之分

2、 所谓的 mutable 和 immutable

在谈mutable 和 immutable 之前,我们先来验证一下 python中的变量就像C语言中的指针变量 这一说法,下面看一段代码:

>>> a = 0
>>> id(a)
6578272L
>>> b = 0
>>> id(b)
6578272L
>>> id(0)
6578272L

可以清楚地看到,a, b 变量都是指向同一个0对象

下面来看一下所谓的mutable 和 immutable , 我们先来看一段代码:

>>> a = 1
>>> print(id(a))
6578248
>>> a = 0
>>> print(id(a))
6578272

可以看到,a的值发生改变后,其指向的对象也发生了改变,a是immutable类型的对象,下面再来看一下mutable类型的对象:

>>> b = [1,2,3]
>>> id(b)
52275976L
>>> b[0] = 2
>>> id(b)
52275976L

可以看到,当b[0]的值改变之后,b所指向的对象并没有发生改变,然而,我们注意到,这里和上面a的值的改变并不是同一个层次,如果是下面这样:

>>> b = [1,2,3]
>>> id(b)
52267656L
>>> b = [2,3,4]
>>> id(b)
52274120L

可以看到, b的指向发生了变化~~
到此为止,我们可以来总结一下,所谓的mutable对象,实质上指的是对象的值的值可以改变,这里,b变量所指向的对象是列表[1, 2, 3] 和 [2, 3, 4],拿 b = [1, 2, 3]来说,它的值是指变量b[0],b[1],b[2],而b[0] = 2 改变的是b[0]的指向,并没有改变b的指向

这样一来,一个对象只要包含多个变量,它便是mutable的,于是,我们可以写一个简单的自定义类来验证一下:

>>> class Test(object):
    def __init__(self):
        self.value = 0


>>> t = Test()
>>> id(t)
44293592L
>>> id(t.value)
6578272L
>>> t.value = 1
>>> id(t)
44293592L
>>> id(t.value)
6578248L

这说明之前的想法是正确的, mutable, immutable的探究到此告一段落。

3、 函数传参

事实上, 理解了以上内容,对于函数传参的理解也应该没有什么问题了
这里还是进行验证一下:

>>> def test(i):
    print(id(i))
    i = 1
    print(id(i))


>>> i = 0
>>> id(i)
6578272L
>>> test(i)
6578272     #可以看到,参数传递其实传递的是对象!
6578248

下面再用一个mutable对象来验证一下:

>>> def test(l):
    print('id(l):',id(l))
    print('id(l[0]):',id(l[0]))#1
    l[0] = 'a'
    print('l[0] changed, id(l):',id(l))
    print('l[0] changed, id(l[0]):',id(l[0]))#2
    l = ['a','b']#a
    print('l changed,id(l):',id(l))
    print('l changed,id(l[0]):',id(l[0]))#3


>>> l = [1,2]
>>> print(id(l))
52243400    #a
>>> test(l)
('id(l):', 52243400L)
('id(l[0]):', 6578248L)         #1
('l[0] changed, id(l):', 52243400L) #可以看到,l的指向并没有因为l[0]的改变而发生变化
('l[0] changed, id(l[0]):', 44073168L)  #2
('l changed,id(l):', 52267912L) 
('l changed,id(l[0]):', 44073168L)
>>> print(id(l))#a   l的指向并没有因为a操作而发生变化,对比上面可以证明
52243400    #函数传参传的就是对象,而非变量
>>> print(id(l[0]))#观察上面1,2,可以发现,l[0]的指向可以通过函数
44073168    #发生变化,这就是所谓的mutable
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值