对象和引用

作者: 姚钢强 | 来源:发表于2013-03-10 16:45 被阅读656次

    对象:

    内存中存放的一块逻辑的整体数据对象具有唯一的标识符,对象包括属性(Properties)和方法(Methods),属性就是需要记忆的信息,方法就是对象
    能够提供的服务。在面向对象(Object Oriented) 的软件中,对象(Object)是某一个类(Class)的实例(Instance)。在python中输入dir(2)
    可以知道,在python中2并不是简单的一个整数,而且包含了很多内置的方法。

    引用:

    引用像指针一样指向一块内存空间,跟c语言中的指针相似。

    举例:

    整数对象

    简单的赋值语句 a = 10000, a 指向了 10000 所在的那块内存。a 引用的对象就是存放 1 的内存地址。is 判断两个变量是否引用同一个对象,id()取得对象的内存地址

    a = 10000
    b = 10000
    print a is b
    

    输出是 False, 可以知道a,b是两个不同的对象,每次创建都会申请新的内存

    a = 1
    b = 1
    print a is b
    

    输出是 True,a,b又是相同的对象了。这是因为在python启动的时候,常用的常数[-5, 256]就建立好,不销毁的对象,也就是a,b都引用相同的>一块内存(存放10000的内存),每次创建这个范围内的整数对象不会申请新的内存。这是个设计上的均衡,用一些内存的浪费,来提高大部分程序>的运行速度

    容器对象

    python中容器(可以包含其他对象的对象)中存放的对象实际上都是引用

    In [17]: a = [[]] * 5
    In [18]: a
    Out[18]: [[], [], [], [], []]
    In [19]: a[1].append(0)
    In [20]: a
    Out[20]: [[0], [0], [0], [0], [0]]
    In [21]: a[0] is a[1]
    Out[21]: True
    

    a 列表有五个相同的元素,这五个元素都是对同一个空列表的引用(21行),所以改变其中任何一个元素(不改变对象引用的情况下),所有的五个元>素都会同时进行改变

    list 是可变对象,在list扩容的时候有几种方法

    In [6]: a = [1]
    In [7]: id(a)
    Out[7]: 28048488
    In [8]: a = a + [2]
    In [9]: a
    Out[9]: [1, 2]
    In [10]: id(a)
    Out[10]: 28047696
    

    可以看出使用 + 修改列表,创建了新的列表(对象),a 已经不是原先那个对象,不存放在原先那个内存地址了,进行了大量的内存复制

    In [21]: a = [1]
    In [22]: id(a)
    Out[22]: 20913832
    In [23]: a += [2]
    In [24]: id(a)
    Out[24]: 20913832
    

    使用 += 修改列表,并没有创建新的列表(对象),还存放在原先那个地址。(extend 与 += 几乎相同,只是extend多了调用函数的时间)。

    In [29]: a = [1]
    In [30]: id(a)
    Out[30]: 28048704
    In [31]: a.append(2)
    In [32]: id(a)
    Out[32]: 28048704
    

    使用 append 修改列表,也没有创建新的列表,也是存放在原先那个地址。append会进行提前的内存申请,扩容时会更快。但是 append 只能进行单个元素的扩容,内存消耗较大。

    所以列表扩容的时候尽量使用 extend 或者 append(当然 list 如果进行频繁大量空间的扩容,肯定会造成效率问题)。

    string 和 tuple 都是不可变对象,所以在进行改变的时候肯定都会创建新的对象。(根据这个原理,可以思考下为什么 string 进行合并的时候为什么建议用join)

    函数对象

    在 python 中函数也是对象,所以我们可以像整数赋值一样,将函数赋值给一个变量,将函数作为参数传递给另一个函数,我觉得这也是为什么python中存在 decorator 的一个原因

    参考:

    http://zh.wikipedia.org/wiki/%E5%AF%B9%E8%B1%A1_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6

    python群 22507237 的 @冒泡 大神

    相关文章

      网友评论

        本文标题:对象和引用

        本文链接:https://www.haomeiwen.com/subject/kzcttttx.html