在python中测试可变性
我正在做一个简单的测试来验证可变性我有一个变量var 我想验证=assignment运算符是否更改了它在同一内存位置的值 var=1 要打印var的地址,我需要 hexidvar它给我“0x1b65158”,然后我分配新值var=2,但现在hexidvar更改为“0x1b65140”,如果它更改相同的位置,它应该返回相同的值,不是吗?请解释一下在python中测试可变性,python,mutable,Python,Mutable,我正在做一个简单的测试来验证可变性我有一个变量var 我想验证=assignment运算符是否更改了它在同一内存位置的值 var=1 要打印var的地址,我需要 hexidvar它给我“0x1b65158”,然后我分配新值var=2,但现在hexidvar更改为“0x1b65140”,如果它更改相同的位置,它应该返回相同的值,不是吗?请解释一下 注意:我不想做上面提到的同样的作业。我试图理解它是如何变化的。我不想在这里创造常数 这可能有助于您了解正在发生的事情: In [1]: hex(id(1
注意:我不想做上面提到的同样的作业。我试图理解它是如何变化的。我不想在这里创造常数 这可能有助于您了解正在发生的事情:
In [1]: hex(id(1))
Out[1]: '0x109af50a0'
In [2]: hex(id(2))
Out[2]: '0x109af50c0'
In [3]: var = 1
In [4]: hex(id(var))
Out[4]: '0x109af50a0'
In [5]: var = 2
In [6]: hex(id(var))
Out[6]: '0x109af50c0'
请注意,id跟在值后面,而不是变量后面
查看内置id的文档也可能会有所帮助:
I对象
返回对象的“标识”。这是一个整数,保证该对象在其生存期内唯一且恒定。两个生命周期不重叠的对象可能具有相同的id值
CPython实现细节:这是内存中对象的地址
当我们编写像hexidvar这样的东西时,我们需要存储在var中的对象地址的十六进制版本
如果我们想测试var是否是不可变的,我们唯一的选择就是尝试给它赋值,并检查是否发生异常
事实上,在Python中声明一个不能更改的变量是不可能的。最接近的方法是声明一个类的实例,如果您试图为其属性赋值,该类会引发异常。有关这方面的更多信息,请参见此问题:
Python的一些实现为-5到256之间的所有整数保留一个整数对象数组。这意味着,当您在该范围内创建int时,实际上只返回对现有对象的引用 例如:
id(1)
--> 8790876942080
x = 1
id(x)
--> 8790876942080
id(5555555555)
--> 89108592
x = 5555555555
id(x)
--> 89109104
因此,当您将新值1或2指定给变量时,实际上是将引用指定给这些现有对象
如上所述,这种行为并不适用于所有整数,例如:
id(1)
--> 8790876942080
x = 1
id(x)
--> 8790876942080
id(5555555555)
--> 89108592
x = 5555555555
id(x)
--> 89109104
您可以在此处阅读更多内容:
如果我理解正确,则可能重复-int是不可变的,因此重新分配它也会更改位置是有意义的。@ItamarMushkin您是对的!!感谢@DavidCullen的可能副本它不是关于创建常量的:那么有什么方法可以测试位置的可变性吗?如果试图分配给变量会引发异常,那么它可能是不可变的。您必须检查异常。这是免疫性测试Yes。如果分配给变量的尝试未引发异常,则该变量是可变的。Python变量就像C指针:它存储访问值所需的信息。在CPython中,存储在变量中的信息是值的地址。但是没有办法阻止Python变量存储不同的地址。当人们在Python中谈论可变性时,他们谈论的是值的可变性。list类型的值是可变的,tuple类型的值是不可变的。所以,当你试图测试一个变量是否是可变的时,我完全搞糊涂了。那么你知道我如何交叉验证赋值运算符在同一内存中修改这个值吗location@YugandharChaudhari,我认为存在于某个内存位置的值的概念可能有点误导。我发现Georgy在第一条评论中提供的答案在这里特别有用,我引用了其中的话:“在Python中,C-a变量不是值所在的位置。这只是一个名字。当你这样做的时候:a=10b=a,你没有把b变成对a的引用。这种想法在Python中甚至没有意义。你把a变成一个10的名字,然后把b变成另一个10的名字,所以它们就像标签一样,对吗?那个么,这个名字的地址实际上是10?