美文网首页
Fluent Python笔记--垃圾回收

Fluent Python笔记--垃圾回收

作者: MontyOak | 来源:发表于2018-01-21 21:18 被阅读22次

在复制list时,默认是做了浅拷贝(shallow copy),也就是说复制了最外层垯容器,而内部元素则是原容器的引用。这么做在内部元素都是不可变类型的时候没有问题,但是在内部包含可变元素的时候会发生一些意想不到的情况:

>>> l1 = [3, [66, 55, 44], (7, 8, 9)]
>>> l2 = list(l1) 
>>> l1.append(100) 
>>> l1[1].remove(55) 
>>> print('l1:', l1)
l1: [3, [66, 44], (7, 8, 9), 100]
>>> print('l2:', l2)
l2: [3, [66, 44], (7, 8, 9)]
>>> l2[1] += [33, 22] 
>>> l2[2] += (10, 11) 
>>> print('l1:', l1)
l1: [3, [66, 44, 33, 22], (7, 8, 9), 100]
>>> print('l2:', l2)
l2: [3, [66, 44, 33, 22], (7, 8, 9, 10, 11)]

所以,当容器中包含可变元素的时候,为了避免意想不到的情况发生,推荐使用深拷贝,即copy.deepcopy
Python中的函数传参是共享传参(call by sharing),即函数形参获得实参中各个引用的副本。带来的副作用是函数内部的操作可能会影响到可变类型的实参。

>>> def f(a, b):
... a += b
... return a
...
>>> x = 1
>>> y = 2
>>> f(x, y)
3
>>> x, y 
(1, 2)
>>> a = [1, 2]
>>> b = [3, 4]
>>> f(a, b)
[1, 2, 3, 4]
>>> a, b 
([1, 2, 3, 4], [3, 4])
>>> t = (10, 20)
>>> u = (30, 40)
>>> f(t, u)
(10, 20, 30, 40)
>>> t, u 
((10, 20), (30, 40))

Python默认解释器CPython中,默认使用引用计数来做垃圾回收。每个对象维护一个变量,计算自己被引用的次数,当这个值归零之后,对象被销毁,执行__del__方法。对于有循环引用的对象,则使用分代垃圾回收算法。

按照上面的说法,引用数归零之后对象被垃圾回收。有时需要引用对象而不想让它存活超过所需时间,比如缓存。
这时候就需要引入弱引用的概念。

>>> import weakref
>>> a_set = {0, 1}
>>> wref = weakref.ref(a_set) 
>>> wref
<weakref at 0x100637598; to 'set' at 0x100636748>
>>> wref() 
{0, 1}
>>> a_set = {2, 3, 4} 
>>> wref() 
{0, 1}
>>> wref() is None 
False
>>> wref() is None 
True

下面演示 WeakValueDictionary的用法:

class Cheese:
    def __init__(self, kind):
        self.kind = kind
    def __repr__(self):
        return 'Cheese(%r)' % self.kind

>>> import weakref
>>> stock = weakref.WeakValueDictionary() 
>>> catalog = [Cheese('Red Leicester'), Cheese('Tilsit'),
... Cheese('Brie'), Cheese('Parmesan')]
...
>>> for cheese in catalog:
... stock[cheese.kind] = cheese 
...
>>> sorted(stock.keys())
['Brie', 'Parmesan', 'Red Leicester', 'Tilsit'] 
>>> del catalog
>>> sorted(stock.keys())
['Parmesan'] 
>>> del cheese
>>> sorted(stock.keys())
[]

相关文章

  • Fluent Python笔记--垃圾回收

    在复制list时,默认是做了浅拷贝(shallow copy),也就是说复制了最外层垯容器,而内部元素则是原容器的...

  • golang 基础

    JUST笔记 Go语言主要特性 自动垃圾回收(Python: so easy?) 丰富内置类型(Python: I...

  • Python垃圾回收机制

    垃圾回收机制: Python中的垃圾回收算法是采用引用计数, 当一个对象的引用计数为0时, Python的垃圾回收...

  • python和ruby的GC

    Python垃圾回收机制--完美讲解!

  • python的GC

    python垃圾回收机制 Python GC 主要是引用计数来跟踪和回收垃圾。 在引用技数的基础上, 通过"标记-...

  • Day11-Python垃圾回收机制笔记

    Python中的垃圾回收是以引用计数为主,标记清除和分代回收为辅。 【引用计数】 Python默认的垃圾收集机制是...

  • python拾遗7 - 垃圾回收

    垃圾回收机制 相比 C++ 的手动回收内存,python 的垃圾回收机制可谓是省心省力,判断是否回收一块内存,主要...

  • Python 垃圾回收学习

    垃圾回收机制一般有两个阶段:垃圾检测和垃圾回收。Python GC 主要使用引用计数来跟踪和垃圾回收。在引用计数的...

  • python面试题(五)

    1、简述python引用计数机制(联想到垃圾回收机制)python垃圾回收主要以引用计数为主,标记-清除和分代清除...

  • Python Metaprogramming

    Fluent Python Metaprogramming 部分的笔记, 在加上了其他杂七杂八的东西 Dynami...

网友评论

      本文标题:Fluent Python笔记--垃圾回收

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