我写这篇文章是为了扩展我对pointers和memory-addressing如何在python中工作的理解。
python是一种高级语言,我了解到内存管理是由Python负责的。
我还了解到,指针可以用id()对象来标识。
假设我有两个变量a和b,这两个变量可以用下面的命令交换:
a,b=b,a使用以下方法可以发现这些变量的identity的变化。
>>> a=2
>>> b=3
>>> id(a)
140732857872688
>>> id(b)
140732857872720
>>> a,b=b,a
>>> a
3
>>> b
2
>>> id(a)
140732857872720
>>> id(b)
140732857872688正如你所看到的,变量被交换了(正如预期的那样),换句话说,我们可以说分配给ids的ids被交换了。这在python中是如何发生的?
在另一个例子中,
>>> i=0
>>> id(i)
140732857872624
>>> i+=1
>>> id(i)
140732857872656当1递增i时,如何在幕后创建具有相同名称的新变量(我将其命名为new,因为标识正在更改)?
我又增加了一个例子来进一步扩展我的问题!
操作1:
>>> i,j=0,0
>>> id(i)
140732857872624
>>> id(j)
140732857872624
>>> i,j = i+1,i+1
>>> i
1
>>> j
1
>>> id(i)
140732857872656
>>> id(j)
140732857872656操作2:
>>> i,j=0,0
>>> i=i+1
>>> j=i+1
>>> i
1
>>> j
2
>>> id(i)
140732857872656
>>> id(j)
140732857872688当然,操作1和操作2是不同的。这两个操作是如何在低级别上发生的。
一旦已经分配的指针不再被使用,它将如何被重用?如果某个memory-address在某个程序中不能重用,并且每个新操作(在同一个程序中)都必须给出新的memory-address,这是使用高深度recursion时内存溢出的原因吗?
我希望我的问题已经说得很清楚了。
如果我的理解有误,请纠正我。来自机械工程的背景,虽然我已经编程了相当长的一段时间,但这个东西真的让我感到困惑。
问候
发布于 2020-06-26 13:45:36
使用dis查看幕后发生的事情。
In [1]: import dis
In [2]: def swap(): a=1; b=2; a,b=b,a
In [3]: dis.dis(swap)
1 0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (a)
4 LOAD_CONST 2 (2)
6 STORE_FAST 1 (b)
8 LOAD_FAST 1 (b)
10 LOAD_FAST 0 (a)
12 ROT_TWO
14 STORE_FAST 0 (a)
16 STORE_FAST 1 (b)
18 LOAD_CONST 0 (None)
20 RETURN_VALUE发布于 2020-06-26 13:52:44
要理解发生了什么,一个简单的心理模型是
即使在Python内部的i=1之后,i也是一个指向包含值1的对象的指针。即使是整数也是普通对象(这在其他语言中并不常见,因为在其他语言中,通常变量最终都会直接包含小整数的值)。
小整数被缓存,所以在Python程序中,所有值为0的变量都将是指向同一对象的指针。在第二种情况下,您观察到不同的id,因为值不同(i将指向1,j将指向2)。
请注意,共享仅针对不可变的对象进行,因为除非使用id,否则无法在代码中观察到共享。在Python语言中,这是针对较小的数字和一些较小的字符串(以"interned").结尾的字符串
发布于 2020-08-14 07:08:37
在python中,变量是内存引用。当您创建
a=2python内存管理器将把这个值2放在内存堆的一个插槽中,并将这个内存插槽的地址分配给变量。本质上
a=adress_of_this_memory_slot在幕后,每当您调用为时,python内存管理器都会查看地址并检索值。
如果对象是不可变的,Python内存管理器会自动重用内存引用。在您的例子中,整数是不可变的对象。所以python按需重用对象,这在python中称为INTERNING。
在启动时,python预加载或缓存-5,256范围内的整数的全局列表。只要在这个范围内引用了一个整数,Python就会使用该对象的缓存版本。
因此根据您的第一个示例,您创建了:
a=2
b=3因此python内存管理器会将这些值添加到两个不同的内存堆插槽中。在您的示例中,它们的地址是:
id(a) ==> 140732857872688
id(b) ==> 140732857872720在此之后,任何时候您想要使用int 2,3时,python都会出于优化的目的使用这些内存地址。
用超出这个范围-5,256的整数来尝试你的例子。您将看到python将为这个变量重新创建一个新地址,换句话说,python将不会共享这些值的引用。
https://stackoverflow.com/questions/62588690
复制相似问题