精华内容
下载资源
问答
  • python 引用计数

    2018-05-22 22:17:00
    要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。 sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为调用函数的时候传入a,这会让a的引用计数+1 二、引用计数的增减 2.1 ...

    转载:NeilLee(有修改)

     

    一、概述

    要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。

     

    sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为调用函数的时候传入a,这会让a的引用计数+1

     

    二、引用计数的增减

    2.1 增加引用计数

    当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1。

    对象的引用计数增加的情况:

    • 对象被创建:x = 3.14
    • 另外的别名被创建:y = x
    • 对象被作为参数传递给函数(新的本地引用):foobar(x)
    • 对象成为容器对象的一个元素:myList = [123, x, 'xyz']

    2.2 减少引用计数

    对象的引用计数减少的情况:

    • 一个本地引用离开了其作用范围。如fooc()函数结束时,func函数中的局部变量(全局变量不会)
    • 对象的别名被显式销毁:del y
    • 对象的一个别名被赋值给其他对象:x = 123
    • 对象被从一个窗口对象中移除:myList.remove(x)
    • 窗口对象本身被销毁:del myList

    2.3 del语句

    Del语句会删除对象的一个引用,它的语法如下:del obj[, obj2[, ...objN]]

    例如,在上例中执行del y会产生两个结果:

    • 从现在的名称空间中删除y
    • x的引用计数减1

     

    转载于:https://www.cnblogs.com/fuqia/p/9074451.html

    展开全文
  • 主要介绍了Python引用计数操作,结合实例形式分析了Python引用计数相关操作与运行机制,需要的朋友可以参考下
  • (给机器学习算法与Python学习加星标,提升AI技能)本文将会为你介绍Python引用计数,演示中使用可变列表对象,不过本文不介绍C语言实现细节。需要注意的是,代码段的输出在硬件上...

    (给机器学习算法与Python学习加星标,提升AI技能) 

     

    本文将会为你介绍Python引用计数,演示中使用可变列表对象,不过本文不介绍C语言实现细节。

    需要注意的是,代码段的输出在硬件上可能有所不同。

     

    变量是内存引用

    Python中的变量是内存引用。如果输入x = [1,2]时会发生什么?[1,2]是对象。

    回想一下,一切都是Python中的对象。[1,2]将在内存中创建。x是[1,2]对象的内存引用。

    来看看下面的例子。可以找到x所引用的内存地址。请务必只使用id(x),它会以10为基数,而十六进制函数会将其转换为十六进制。

    1x = [1, 2]
    2print(hex(id(x)))  # output: 0x32ebea8
    

    引用计数

    现在已经在内存中创建了一个list对象,而且x对该对象进行了引用。那么y=[1,2]和y=x有什么区别?

    当输入y=[1,2]时,它将在内存中创建一个新的list对象,并且y将引用它。 

    1x = [1, 2]
    2y = [1, 2]
    3print(hex(id(x)))  # output: 0x101bea8
    4print(hex(id(y)))  # output: 0x31a5528
    

    而当输入y=x时,等同于告诉Python希望y 变量引用x变量引用的内容。因为变量是内存引用的。

     

    可以确认x和y引用同一个对象。

    1x = [1, 2]
    2y = x
    3print(hex(id(x)))  # output: 0x74bea8
    4print(hex(id(y)))  # output: 0x74bea8

    引用计数的数目

    接下来的问题是,有多少变量引用同一个对象?

     

    错误的用法:

     

    我看到有些人在使用sys.getrefcount(var)时不知道如何传递var,而是向对象添加引用。一起看看下面的例子。

    输出3,而期望的却是2(x andy)。发生这种情况是因为将x传递给getrefcount函数时又添加了一个引用。

    1from sys import getrefcount
    2x = [1, 2]
    3y = x
    4print(hex(id(x)))  # output: 0xb65748
    5print(hex(id(y)))  # output: 0xb65748
    6print(getrefcount(x))  # output: 3
    

    更好的用法:

    可以使用内置的ctypes模块来找到预期的结果。必须将x的id传递给from_address函数。

    1from ctypes import c_long
    2x = [1, 2]
    3y = x
    4print(hex(id(x)))  # output: 0x3395748
    5print(hex(id(y)))  # output: 0x3395748
    6print(c_long.from_address(id(x)).value)  # output: 2

    概言之,错误的用法是传递变量,而更好的用法则是传递变量的id,这意味着只传递基数为10的数字,而不是变量。

     

    当对象消失时

    当没有变量引用对象时会发生什么?

    对象将从内存中删除,因为没有引用该对象的内容。不过也有例外:如果有循环引用,garbage collector 将开始奏效。

    为什么使用可变对象

    不可变对象由于性能原因,结果可能与预期不同。查看下面的例子,观察输出是如何变化的。

     1import sys
     2import ctypes
     3"""Some Mutable Objects """
     4a =list()
     5b =set()
     6c =dict()
     7d =bytearray()
     8""" Some ImmutableObjects """
     9e =tuple()
    10f =int()
    11g =str()
    12      print(sys.getrefcount(a),ctypes.c_long.from_address(id(a)).value)  # output: 2 1
    13      print(sys.getrefcount(b),ctypes.c_long.from_address(id(b)).value)  # output: 2 1
    14      print(sys.getrefcount(c),ctypes.c_long.from_address(id(c)).value)  # output: 2 1
    15      print(sys.getrefcount(d),ctypes.c_long.from_address(id(d)).value)  # output: 2 1
    16      print(sys.getrefcount(e),ctypes.c_long.from_address(id(e)).value)  # output: 1298 1297
    17      print(sys.getrefcount(f),ctypes.c_long.from_address(id(f)).value)  # output: 209 208
    18      print(sys.getrefcount(g),ctypes.c_long.from_address(id(g)).value)  # output: 59 58
    

    文中所谈及的一切都对CPython有效。希望对你有帮助。

    相关链接:

    https://medium.com/better-programming/a-guide-to-reference-counting-in-python-27334fc2e3c1

    推荐阅读
    弄懂这八个神经网络架构,深度学习才算入门!
    
    【一】零基础入门深度学习:用numpy实现神经网络训练
    
    2020全球顶尖计算机科学家排名发布:两位华人学者入全球前10,Top 1000华人学者过百
    曲线救国:提高github下载速度到2MB/s
    
    
    
    
    展开全文
  • python引用计数原理

    2019-11-18 14:37:53
    要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。 sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为调用函数的时候传入a,这会让a的引用计数+1 二、引用计数的增减 2.1 ...

    一、概述

    要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。

     

    sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为调用函数的时候传入a,这会让a的引用计数+1

     

    二、引用计数的增减

    2.1 增加引用计数

    当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1。

    对象的引用计数增加的情况:

    • 对象被创建:x = 3.14
    • 另外的别名被创建:y = x
    • 对象被作为参数传递给函数(新的本地引用):foobar(x)
    • 对象成为容器对象的一个元素:myList = [123, x, 'xyz']

    2.2 减少引用计数

    对象的引用计数减少的情况:

    • 一个本地引用离开了其作用范围。如fooc()函数结束时,func函数中的局部变量(全局变量不会)
    • 对象的别名被显式销毁:del y
    • 对象的一个别名被赋值给其他对象:x = 123
    • 对象被从一个窗口对象中移除:myList.remove(x)
    • 窗口对象本身被销毁:del myList

    2.3 del语句

    Del语句会删除对象的一个引用,它的语法如下:del obj[, obj2[, ...objN]]

    例如,在上例中执行del y会产生两个结果:

    • 从现在的名称空间中删除y
    • x的引用计数减1
    展开全文
  • python 引用计数问题

    千次阅读 2019-04-21 15:25:35
    文章目录对象的引用计数+1的情况:对象被创建对象被引用...python的垃圾回收采用的是引用计数机制为主和分代回收机制为辅的结合机制,当对象的引用计数变为0时,对象将被销毁,除了解释器默认创建的对象外。(默认...


    python的垃圾回收采用的是引用计数机制为主和分代回收机制为辅的结合机制,当对象的引用计数变为0时,对象将被销毁,除了解释器默认创建的对象外。(默认对象的引用计数永远不会变成0)

    对象的引用计数+1的情况:

    1. 对象被创建

    >>> import sys
    >>> a = 23
    >>> sys.getrefcount(a)
    6
    

    这里23这个对象并没有在内存中新建,因为在Python启动解释器的时候会创建一个小整数池,-5~256之间的这些对象会被自动创建加载到内存中等待调用;a = 23是为23这个整数对象增加了一个引用。

    >>> class MyName():
    ...     pass
    ...
    >>> sys.getrefcount(MyName())
    1
    

    结果为1,是因为sys.getrefcount(MyName())函数也算一个引用。

    2. 对象被引用

    >>> a = 3.1415926
    >>> b = a
    >>> c = b
    >>> sys.getrefcount(a)
    4
    >>> sys.getrefcount(b)
    4
    >>> sys.getrefcount(c)
    4
    

    每一次赋值都会增加数据操作的引用次数,要记住引用的是变量a,b,c等指向的数据 3.1415926 ,而不是变量本身。

    3. 对象被作为参数,传入到一个函数中

    >>> a = 3.1415926   # 增加一个引用  count = 1
    >>> b = a   # 增加一个引用  count = 2
    >>> c = b   # 增加一个引用  count = 3
    >>> sys.getrefcount(b)   # 增加一个引用  count = 4   执行完毕后引用销毁,减少一个引用   count = 3
    4
    >>> sys.getrefcount(c)   # 增加一个引用  count = 4   执行完毕后引用销毁,减少一个引用   count = 3
    4
    

    函数 sys.getrefcount() 调用时 会增加一个引用,调用完又销毁一个引用。 实际上就是实参传给形参的问题。

    4. 对象作为一个元素,存储在容器中

    >>> a = 3.1415926   # 增加一个引用  count = 1
    >>> sys.getrefcount(a)
    2
    >>> b = a   # 增加一个引用  count = 2
    >>> sys.getrefcount(a)
    3
    >>> list_ = [a, b]   # 增加两个引用  count = 4
    >>> sys.getrefcount(a)
    5
    

    对象的引用计数-1的情况:

    1. 对象的别名被赋予新的对象

    >>> a = 3.1415926   # 增加一个引用  count = 1
    >>> b = a   # 增加一个引用  count = 2
    >>> sys.getrefcount(a)
    3
    >>> b = -3.1415926   # 原对象减少一个引用  count = 1
    >>> sys.getrefcount(a)
    2
    

    2. 对象的别名被显式销毁

    >>> a = 3.1415926   # 增加一个引用  count = 1
    >>> b = a   # 增加一个引用  count = 2
    >>> sys.getrefcount(a)
    3
    >>> del b   # 减少一个引用  count = 1
    >>> sys.getrefcount(a)
    2
    

    3. 一个对象离开它的作用域

    >>> a = 3.1415926   # 增加一个引用  count = 1 
    >>> sys.getrefcount(a)   # 增加一个引用  count = 1  ==>   打印 2  ==>  减少一个引用  count = 1
    2
    

    a 作为参数传递到 sys.getrefcount(a) 函数中,只在函数中起作用,一旦执行完毕就会销毁。

    4. 对象所在的容器被销毁,或从容器中删除对象

    >>> a = 3.1415926
    >>> sys.getrefcount(a)
    2
    >>> list_ = [a,1,2,3]
    >>> sys.getrefcount(a)
    3
    >>> del list_
    >>> sys.getrefcount(a)
    2
    
    展开全文
  • Python引用计数机制

    2019-10-19 17:12:03
    1.Python 程序在运行时,需要在内存中开辟出一块空间,用于存放运行时产生的临时变量,计算完成后,再将结果输出到永久性存储器中。 2.但是当数据量过大,或者内存空间管理不善,就很容易出现内存溢出的情况,程序...
  • python引用计数和gc垃圾回收

    千次阅读 2017-03-05 13:46:15
    python采用"引用计数"和"垃圾回收"两种机制来管理内存。 引用计数通过记录对象被引用的次数来管理对象。 对对象的引用都会使得引用计数加1,移除对对象的引用,引用计数则会减1, 当引用计数减为0时,对象所占的内存...
  • 对象引用计数增加的情况: 1.对象被创建:x=4 2.另外的别人被创建:y=x 3.被作为参数传递给函数:foo(x) ->会增加2 4.作为容器对象的一个元素:a=[1,x,'33'] 对象引用计数减少的情况: 1.一个本地引用...
  • Python引用计数的三种方式

    千次阅读 2017-07-20 17:39:59
    Python源码及扩展模块中,对引用计数的使用有三种方式: 拥有引用、 借用引用和窃取引用。   拥有引用:拥有引用比较简单,针对PyObject对象调用Py_INCREF或Py_XINCREF即可,如将一个对象加入到字典中时,会...
  • 接下来通过 weakref.ref() 创建一个弱引用,通过 getrefcount 打印引用计数后,发现计数并没有改变。 w() is a 这句的意思是判断这两个实例是不是完全相同,也就是占用的内存地址是否相同。 然后我们通过 del a ...
  • python引用计数和垃圾回收 引用计数 所有对象都有引用计数。给一个对象分配一个新名称,或是将其放入一个容器,都会增加该对象的引用计数 a = 37 b = a c = [] c.append(b) 这是一个包含值37的对象,a只是引用这个...
  • python引用计数机制

    千次阅读 2018-11-06 20:17:26
    python内部使用引用计数,来保持追踪内存中的对象, Python内部记录了对象有多少个引用 ,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。 总结一下...
  • Python引用计数

    2017-01-07 15:56:00
    要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。 二、引用计数的增减 2.1 增加引用计数 当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1。 对象的引用计数增加的情况: 对象被...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,080
精华内容 832
关键字:

python引用计数

python 订阅