流畅的python(三)—list方法、深浅拷贝、python内存分析

list类实现的特殊函数对应的方法以及自己实现的一些方法:

内置的:+ , +=, *, *+, ~*      (__add__, __iadd__, __mul__,__imul__,__rmul__)(mul是list*n,rmul)(rmul是n*list)

            for,    in,    [],   [],            ( __iter__, __next__, __contiain__,__getitem__,__setitem__)

            len,  sorted,   reversed      (__len__ , 无, __reversed__) 

            注:sorted无特殊函数,reversed有特殊函数,但是reversed有没有均可以用。

包含的:appand, insert   extend, 

             remove,    pop,   del,  clear   (del有特殊函数__delitem__)

             [](上面内置的)

             index,      [] (上面内置的)  , in(上面内置的)

             sort,    reverse,   copy,  count

这里涉及到了copy,那我们研究一下深拷贝和浅拷贝

  • 首先说明一下python的内存模型
  • python在执行代码解释的过程中,所有对象创建的时候都会分配内存空间,如7种数据类型、4种数据结构(str也可认为是一种数据结构)、类(不包括类内函数)、类的实例、一般函数(包括关键字传参),但是不管如何分配,在python中数据对象只有两种,一种是可变对象,一种是不可变对象。不可变的是7种数据类型和tuple这个数据结构,可变的是剩下的三种数据结构,所谓对象就是这个类就是对象,如3这就是个int类,如a=3,那么3就是这里的对象就不可变,a是这个对象的实例,这里的对象不是指实例,在如a=[1], [1]这个就是可变对象。二者的根本区别就是内存地址到底是否可以变化。前者不可变。后者是可变。所谓可变就是a=[1]和b=[1]里面这两个[1]地址不同,系统会分别开辟内存地址,所谓不可变就是a=1,b=1,里面的这两个1地址一样,不可变。这里的对象就是值,python是为值分配空间,而C是为变量分配空间,这是本质的区别。
  • 记住,python都是引用传参,即当前实例就是这个对象的地址,如a=3,那么a就是地址,但是直观来看a=3,所以乍一看a是3,但是python是引用传值,所以a本质上存储的是3的地址,因为是引用传参,所以这里不会存储3,只会存储3的引用。
  • 看下面例子:
  • 流畅的python(三)—list方法、深浅拷贝、python内存分析
  • 上面就是浅拷贝,当然对于第一层是深拷贝,但是总的来看还是浅拷贝。浅拷贝总共三种方法:第一就是上面的copy,第二是切片,第三是列表解析得到的list,深拷贝就是deepcopy(),不管套多少层,都能拷贝下来。具体的实现细节后面再看。
  • 说明:上述红色的是tuple专用的,要知道tuple是不可变数据结构,所以它存储在不可变对象区域,但是里面的元素可以是可变对象,所以里面的可变对象的元素是可以更改的。要注意不可变的原因是什么。