假设我有以下代码:
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/