垃圾回收机制

a 夏天 提交于 2019-12-05 00:08:20
  • [ ] ```python
    https://www.cnblogs.com/zhangchaocoming/p/11192436.html
    https://www.cnblogs.com/liangmingshen/p/10970534.html

    可迭代对象

    内置有__iter__方法的对象,例如字符串,列表,字典,元组等等都是可迭代对象

    迭代器对象

    1. 既内置有__next__方法的对象,执行迭代器__next__方法可以不依赖索引取值
    2. 又内置有__iter__方法的对象,执行迭代器__iter__方法得到的仍然是迭代器本身

      所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator

      生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。

      生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器

    res=(i+1 for i in range(10))#res就是一个生成器
    for i in res:
        print (i)

    python中生成器
    要创建一个generator,有很多种方法,第一种方法很简单,只有把一个列表生成式的[]中括号改为()小括号,就创建一个generator

    所以我们创建一个generator后,基本上永远不会调用next(),而是通过for循环来迭代,并且不需要关心StopIteration的错误,generator非常强大,如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

    for循环(也称之为迭代器循环)的工作原理:

    1,先调用in后面那个对象的__iter__的方法,将其变成一个迭代器对象‘
    
    2,调用next(迭代器),将其得到的返回值赋值给变量名K,

      3,循环往复直到next(迭代器)抛出异常,for会自动捕捉异常,然后结束循环。   

               dic={'x':1,'y':2,'z':3}
    
                 for k in dic:
                     print(k)

    python提供了两种基本的方式

    生成器函数:也是用def定义的,利用关键字yield一次性返回一个结果,阻塞,重新开始

    生成器表达式:返回一个对象,这个对象只有在需要的时候才产生结果

    1.生成器函数
    为什么叫生成器函数?因为它随着时间的推移生成了一个数值队列。一般的函数在执行完毕之后会返回一个值然后退出,但是生成器函数会自动挂起,然后重新拾起急需执行,他会利用yield关键字关起函数,给调用者返回一个值,同时保留了当前的足够多的状态,可以使函数继续执行,生成器和迭代协议是密切相关的,迭代器都有一个__next__()__成员方法,这个方法要么返回迭代的下一项,要买引起异常结束迭代。

    函数有了yield之后,函数名+()就变成了生成器

    return在生成器中代表生成器的中止,直接报错

    next的作用是唤醒并继续执行

    send的作用是唤醒并继续执行,发送一个信息到生成器内部

    '''生成器'''

    def create_counter(n):
    print("create_counter")
    while True:
    yield n
    print("increment n")
    n +=1

    gen = create_counter(2)
    print(gen)
    print(next(gen))
    print(next(gen))

    结果:
    <generator object create_counter at 0x0000023A1694A938>
    create_counter
    2
    increment n
    3
    Process finished with exit code 0

    2.生成器表达式

    迭代器总结:
    优点:
    1,提供一种通用的且不依赖索引的迭代取值的方式
    2,同一时刻在内存中只存在一个值,更节省内存。
    缺点:
    1,取值不如按照索引的方式灵活,(不能区指定的某一个值而且取值是从左往右,)
    2,无法预测迭代器的长度,取完之后会报stopiteration错

    二,生成器:用户自定义的迭代器,本质就是迭代器。优点:节省内存(如果数据量较大,最好不要用列表生成式),代码量更少,执行更高效。

    2.垃圾回收机制

    python的垃圾回收有三种策略

    • 引用计数
    • 分代回收
    • 标记清除

    引用计数:PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了

    分代回收:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。

    标记清除:基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。

    3.迭代器和生成器的区别

    迭代器:是一个更加抽象的概念,任何对象,如果它的类有next方法和iter方法返回自身。对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数,iter()是Python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素时,next()会抛出一个StopIterration的异常。

    生成器:是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在返回数据的时候需要使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)

    总结:生成器能做到迭代器能做的所有事,而且因为自动创建了__iter__()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保持程序状态的自动生成,当发生器终结时,还会自动跑出StopIterration异常。
    ```

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!