假设我有以下代码:

myInt = 5
myInt = 7
myInt2 = 5


整数是不可变的,因此在第2行运行时,Python会停止指向存储5的地址存储器,并开始指向存储7的地址。但是5值仍然存在,但是没有人指向它。


那么Python如何知道第3行运行时的指向?
它是否遍历所有内存块或地址,直到找到值5
还是在内存中将未引用的值存储在高速缓存或表中?


谢谢!

最佳答案

还是在内存中将未引用的值存储在高速缓存或表中?


您在CPython中所做的猜测或多或少是正确的。有一个small integer intern,其中包含-5到256之间的整数(包括CPython默认版本)。每个整数的内存为preallocated,因此您在此处显示的每个赋值语句仅从实习生中检索缓存的对象。

5和7都不会被创建或删除,因为它们已经被实习了,它们将保留在实习生中,直到解释器退出。

因此,分配这些值将仅增加或减少它们的引用计数,正如您可以使用stdlib gc模块检查的那样:

>>> 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


您可以看到从实习生here检索的代码:

#define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS)

...

PyObject *
PyLong_FromLong(long ival)
{
    ...

    if (IS_SMALL_INT(ival)) {
        return get_small_int((sdigit)ival);
    }
    ...
}


注意,整数是一个实现细节。

关于python - 当原始引用现在指向新值时,Python如何知道在何处定位创建的不可变值?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58782688/

10-13 00:08