【问题标题】:testing mutability in python在python中测试可变性
【发布时间】:2019-12-03 10:11:49
【问题描述】:

我正在做一个简单的测试来验证可变性我有一个变量var

我想验证= 赋值运算符是否会更改我正在做的同一内存位置的值

var = 1

打印var的地址我愿意

hex(id(var)) 它给了我'0x1b65158' 然后我分配新值var = 2 但现在hex(id(var)) 更改为'0x1b65140' 如果它正在更改相同的位置,它应该返回相同的不是吗?请解释

注意:我不想做提到here 的相同任务。我试图了解它是如何可变分配的。而且我并不想在这里创建常量。

【问题讨论】:

标签: python mutable


【解决方案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 内置的文档也可能会有所帮助:

id(对象)

返回对象的“身份”。这是一个整数,保证该对象在其生命周期内是唯一且恒定的。具有不重叠生命周期的两个对象可能具有相同的 id() 值。

CPython 实现细节:这是对象在内存中的地址。

当我们写像hex(id(var)) 这样的东西时,我们要求的是存储在var 中的对象地址的十六进制版本。

如果我们想测试var 是否不可变,我们唯一的选择是尝试为它分配一些东西并检查是否发生异常。

事实上,在 Python 中声明一个不能改变的变量是不可能的。最接近的方法是声明一个类的实例,如果您尝试为其属性分配值,则会引发异常。有关这方面的更多信息,请参阅以下问题:

How do I create a constant in Python?

【讨论】:

  • 那么有什么方法可以测试位置的可变性吗?
  • 如果尝试分配给变量引发异常,它可能是不可变的。您必须检查异常。
  • 那是测试不变性
  • 是的。如果尝试分配给变量没有引发异常,则它是可变的。我觉得我在这里指出了显而易见的事情。
  • Python 变量就像 C 指针:它存储访问值所需的信息。在 CPython 中,存储在变量中的信息是值的地址。但是没有办法阻止 Python 变量存储不同的地址。当人们谈论 Python 中的可变性时,他们谈论的是值的可变性。 list 类型的值是可变的,tuple 类型的值是不可变的。因此,当您似乎在尝试测试变量是否可变时,我完全糊涂了。
【解决方案2】:

Python 的一些实现为所有介于 -5 和 256 之间的整数保留了一个整数对象数组。这意味着当您在该范围内创建一个 int 时,实际上您只是获取对现有对象的引用。

例如:

id(1)
--> 8790876942080
x = 1
id(x)
--> 8790876942080

因此,当您将新值 12 分配给您的变量时,您实际上将引用分配给这些现有对象。

正如我上面提到的,这种行为并非对所有整数都一致,例如:

id(5555555555)
--> 89108592
x = 5555555555
id(x)
--> 89109104

您可以在这里阅读更多内容:

  1. ID Function

  2. is Operator

【讨论】:

  • 那么你知道我如何交叉验证赋值运算符修改了相同内存位置的值
  • @YugandharChaudhari,我认为值“坐在”某个内存位置的概念可能有点误导。我发现 Georgy 在第一条评论中提供的答案在这里特别有用,我从那里引用:'在 Python 中——与 C 不同——变量不是值所在的位置。这只是一个名字。这些值可以随心所欲地存在。1 因此,当您这样做时: a = 10 b = a 您没有将 b 变成对 a 的引用。这个想法在 Python 中甚至没有意义。您将 a 变成 10 的名称,然后将 b 变成 10 的另一个名称。'
  • 所以它们就像这里的标签或标签,对吧?那么 name 实际上持有 10 的地址是什么?
猜你喜欢
  • 2018-08-22
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
  • 2023-01-22
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 2016-02-27
相关资源
最近更新 更多