当原始引用现在指向新值时,Python如何知道在何处定位创建的不可变值?

当原始引用现在指向新值时,Python如何知道在何处定位创建的不可变值?,python,memory,python-internals,Python,Memory,Python Internals,假设我有以下代码: myInt = 5 myInt = 7 myInt2 = 5 整数是不可变的,所以当第2行运行时,Python停止指向存储5的地址内存,并开始指向存储7的地址内存。但是5值仍然存在,但没有人指向它 那么Python如何知道在运行第3行时指向何处呢 它是否遍历所有内存块或地址,直到找到值5 还是在内存、缓存或存储未引用值的表中保持分离 谢谢大家! 在python中,堆结构是维护内存,所有的东西都是对象 exa=5这里5是存储在内存中的位置,一个指向它的指针 所以,如果您执行b

假设我有以下代码:

myInt = 5
myInt = 7
myInt2 = 5
整数是不可变的,所以当第2行运行时,Python停止指向存储
5
的地址内存,并开始指向存储
7
的地址内存。但是
5
值仍然存在,但没有人指向它

  • 那么Python如何知道在运行第3行时指向何处呢
  • 它是否遍历所有内存块或地址,直到找到值
    5
  • 还是在内存、缓存或存储未引用值的表中保持分离

  • 谢谢大家!

    在python中,堆结构是维护内存,所有的东西都是对象

    ex
    a=5
    这里5是存储在内存中的位置,一个指向它的指针

    所以,如果您执行
    b=5
    然后执行hex(id(a))==hex(id(b)),则两个对象都指向相同的内存位置

    所以界面是这样的

    python对象--指针模块-->实际内存位置

    所以,若你们改变a的值,比如a=53,然后检查
    hex(id(a))
    ,你们会发现它和之前不同,但对象是相同的。因此,我们可以说新的mmory位置已经完成,中间件python对象分配(不知道正式名称)处理分配(绑定)到新内存位置和对象(a)

    现在问题是,它在内存中保持未分配值5的时间有多长,这完全取决于堆大小—grabage分配器可以存储多少API

    还是在内存、缓存或存储未引用值的表中保持分离

    你上面的猜测在CPython中或多或少是正确的。有一个包含-5到256(包括在内)的整数(在默认的CPython构建中)。每个整数的内存都是,因此这里显示的每个赋值语句只从intern检索缓存对象

    5和7都不会被创建或删除,因为它们已经被实习,并且它们将保留在实习中,直到口译员退出

    因此,分配给这些值只会增加或减少它们的引用计数,您可以使用stdlib模块进行检查:

    您可以看到从intern检索的代码:


    #定义为小整数(ival)(-NSMALLNEGINTS是否缓存5或者是否为第3行创建了5的新实例取决于实现。同样,使用的垃圾收集方法也取决于实现。我需要查看python源代码才能确定,但我的假设是,对于
    int
    变量,它只存储值而不是引用(它们的大小都一样,存储一个值的簿记要少得多).@SamStafford在Python中,甚至整数都是对象,而文本整数会构建对对象的引用。Python会缓存它们。它还会预实例化前100个左右的整数。你可以看看关于如何处理小整数的解释。@Keith我读到了预实例化-5到256个整数并将它们存储在数组中的内容!这就是为什么如果你a=255,b=255,id(a)==id(b)返回True,但如果a=260,b=260,id(a)==id(b)返回False!我很想知道大于256的数字会发生什么!伙计们,我在自学编程,同时掌握了很多概念。这取决于-通常会创建/销毁新对象,除非。谢谢@wim你的答案太棒了!尽管在我学习的早期阶段阅读代码,C公司最重要的是,很难。我不知道如何选择最好的答案,但请记住!!!
    >>> import gc
    >>> def counts():
    ...     print("refcount5:", len(gc.get_referrers(5)))
    ...     print("refcount7:", len(gc.get_referrers(7)))
    ... 
    >>> counts()
    refcount5: 10
    refcount7: 7
    >>> myInt = 5  # this will increment 5's refcount
    >>> counts()
    refcount5: 11
    refcount7: 7
    >>> myInt = 7  # this will decrement 5's refcount and increment 7's
    >>> counts()
    refcount5: 10
    refcount7: 8
    >>> myInt2 = 5  # this will increment 5's refcount
    >>> counts()
    refcount5: 11
    refcount7: 8