python中一些基础知识

1、range和xrange的区别

答:首先说明一点xrange函数属于python2中,在python3中都统一使用range。

    range:创建一个list对象,一般用于for循环中。

    

    xrange:生成一个生成器对象,一般用于for循环中。


注意:当需要生成很大的数字序列时,用xrange函数会比range函数性能优很多,因为range函数是直接开辟内存空间,

2、python中的赋值、浅复制、深复制的区别(注意对象的嵌套

    (1)赋值:复制新对象的引用,不会开辟新的内存空间。

        (2)浅复制:创建新对象,其内容是原对象的引用(仅仅拷贝了一层),分三种形式:切片操作、工厂函数、copy模块中的copy函数。

    切片操作:list1 = list[:] 或者list1 = [i for i in list]

扫描二维码关注公众号,回复: 1946673 查看本文章

    工厂函数:list1 = list(list)

    copy函数:list1 = copy.copy(list)

    (3)深复制:是全新的对象,和原对象没有任何关联。拷贝了对象的所有元素,包括多层嵌套的元素,这是与浅复制的区别。只有一种形式:copy模块中的deepcopy函数。


3、垃圾回收机制

    python的GC模块主用运用了引用计数来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”解决容器对象可能产生的循环引用的问题。通过分代回收以空间换取时间进一步提高垃圾回收的效率。

    (1)引用计数:当一个对象的引用被创建或者复制时,对象的引用计数加1;当一个对象的引用被销毁时,对象的引用计数减1,当对象的引用计数减少为0时,就意味着对象已经没有被使用了,可以将其内存释放。

            优点:实时性,任何内存,一旦没有指向它的引用,就会被立即回收。

            缺点:引用计数机制带来的维护引用计数的额外操作与内存分配和释放,引用赋值的次数成正比。另外,引用计数存在循环引用的问题。

    (2)标记-清除:只关注那些可能会产生循环引用的对象,像不可变对象是不可能产生循环引用的,因为它们内部不可能持有其它对象的引用。python中的循环引用总是发生在container对象之间,也就是能够在内部持有其它对象的对象,比如list、dict、class等等。

            原理:1)垃圾检测动作起点:寻找根对象的集合,根对象是一些全局引用和函数栈中的引用,这些引用所指向的对象是不可删除的

                     2)垃圾检测阶段:寻找可达对象 (沿着根对象集合中的每一个引用,能够达到某个对象) 和不可达对象。

                     3)垃圾回收阶段:保留所有的可达对象回收其它的不可达对象所占用的内存。(底层采用链表将这些集合对象连接在一起)

            缺点:效率不高。

    (3)分代回收:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合称为一个“代”。默认有三代对象集合,垃圾收集的频率随“代”的存活时间的增大而减少。也就是说,存活得越长的对象,就越不可能是垃圾。

            如何衡量存活时间:通常利用几次垃圾搜集动作来衡量,如果一个对象经过的垃圾收集次数越多,那么存活时间越长。

4、可变对象和不可变对象

    (1)不可变对象:该对象所指向的内存中的值不能被改变。不可变类型有:数值类型(int和float)、字符串、元组

                    当改变某个变量时,由于所指向的对象不能改变,相当于需要重新开辟新的内存空间,然后变量重新指向新的内存空间。(我的理解:不可变对象(2)在内存空间中的地址是固定的(1438646800),也就是说不论经过多少种操作,最后结果是2,那么该变量引用(a,b,c)都是指向了2的内存地址。相当于每一个不可变对象具有自己的地址,当变量引用要改变时,先开辟新的内存空间存放另一个不可变对象,然后让变量引用指向这个新的不可变对象,原来的就被垃圾回收了。)(不可变对象创建之后不能改变,如果更改则变量会指向一个新的对象。)


    注意:对于str、int、float,只要类型相同,并且值也相同时,它们的id是相同的。元组有某些地方不太一样。

    (2)可变对象:该对象所指向的内存的值可以被改变。可变类型有:列表、字典、集合

                    当改变某个变量时,由于所指向的值也能改变,因此直接改变该值,不需要重新开辟内存空间。(我的理解:当变量引用要改变时,由于是可变对象,变量引用的值可以直接修改,不需要开辟新的内存空间。相当于变量引用不改变指向的内存地址,而是对其内容进行重写)(即可变对象一旦创建之后还可改变但是地址不会发生改变,该变量指向的还是原来的对象。)


    (3)复制时,不可变对象和可变对象的区别


当复制时,变量引用都是指向的同一个内存地址;当原始的变量引用(上图变量a)改变时:对于可变对象,就是将该内存地址的内容进行重写;对于不可变对象,就是先开辟内存空间存放新的不可变对象(上图中的5),使原始变量引用(上图变量a)指向新的不可变对象, 而复制的变量引用(上图变量b)保持不变。

5、引用传递和值传递

    (1)对于不可变对象,函数传参属于值传递;

    (2)对于可变对象,函数传参属于引用传递。而对于可变对象的拷贝,传递的不是引用,而是值。



猜你喜欢

转载自blog.csdn.net/not_guy/article/details/80756262