一个变量是名称、值还是内存位置?

12

我已经学习 Python 几个月了,也略懂一点 C ,我想知道一个问题:

变量是指名称、值还是内存位置?

比如:

x = 5

变量x是指x的值还是指内存中x的位置?

我正在寻找一个清晰易懂的解释,说明变量是什么。我已经查看了维基百科关于变量这个问题,但对我来说都不太清楚。如果这是一个重复的问题,请提供正确答案的链接。

谢谢!


2
在这种情况下,你不懂C语言反而是一个优势,因为C语言和Python需要以不同的方式思考变量及其所代表的含义。 - SethMMorton
5个回答

13

对于语句 x=5,有几个事情要处理:

  1. 创建了一个值为5的int对象(如果已存在,则找到该对象);
  2. 创建了名称为x(或取消上次标记为“x”的对象关联);
  3. 增加新(或找到的)int对象的引用计数1个;
  4. 将名称x与创建的值为'5'的对象(或找到的对象)相关联。

由于int对象是不可变的,它们可能会被为了效率而进行字符串内部化。字符串对象更有可能被内部化。

以下是一些示例:

>>> x=5    # discussed
>>> id(x)  # the 'id' which in cPython is the memory address.
140246146681256
>>> y=x    # now two names, 'x' and 'y' associated with that object
>>> id(y)  
140246146681256     # same object
>>> z=5    # no guaranteed, likely the same object referred to by 'x' and 'y'
>>> id(z)
140246146681256     # id is the same! The object labeled 'x' was found and labeled 'z'
>>> del x           # ref count to object '140246146681256' decreased by 1
>>> del y           # same
>>> z
5
>>> id(z)
140246146681256    # same object but the names ''x' and 'y' no longer label it

把变量名(如x=5中的'x')看作标签是最好的方式。

有可能会存在没有标签的对象,比如在这个列表推导式中创建的5个独立字符串对象:

>>> li=[str(x) for x in range(5)]  
>>> li
['0', '1', '2', '3', '4']
你可以创建与这5个独立对象的值匹配的对象:
>>> li2=list('012345')    # longer list; completely different construction
>>> li2
['0', '1', '2', '3', '4', '5']    
你可以获取它们在cPython中的单独内存地址或唯一的id地址:
>>> [id(x) for x in li]
[4373138488, 4372558792, 4372696960, 4373139288, 4373139368]
>>> [id(x) for x in li2]
[4373138488, 4372558792, 4372696960, 4373139288, 4373139368,  4372696720]  

请注意,两个独立创建的匿名对象列表是相同的(在这种情况下为前5个)。我有意使用字符串,因为它们更有可能被interned...

所以这样想:使用 x=5 时会发生两个不同的过程:

  1. 创建对象(如果是不可变的、内部化的并存在则找到该对象);
  2. 标记对象。

非常详细,谢谢!所以如果我理解正确,变量是内存中的一个对象和名称之间的链接? - Impossibility
大致正确。在Python中,变量没有像在C语言中那样被广泛使用。我认为更好的方式是将其视为对象的名称或标签。对象可以存在于云端、内存、磁盘上,也可以是待生成的对象等。 - dawg

5

在内存中有一个空间存储值。这些内存通过地址定位,通常呈十六进制或二进制数字表示。对于程序员来说,这些数字难以记忆,因此他们使用术语“变量”以一种简单的方式引用该内存位置,或者可以说是更高的抽象层次。因此,x只是一个名称,指向内存中包含值5的某个位置。就是这样!


1
在Python中,变量最好被视为名称。
对于数字,数字是不可变的,因此重新分配变量将始终使变量指向不同的数字,而不会更改数字。
x = 1
y = x
x += 1 # y is still 1

差异在可变对象中更加明显,您可以更改值或使变量引用不同的值。
x = [1,2,3]
y = x
x.append(4) # I mutated x's value, so y is now [1,2,3,4]
x = [] # I made x point to a different list, so y is still [1,2,3,4]

推荐阅读:

http://web.archive.org/web/20180411011411/http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html

http://me.veekun.com/blog/2012/05/23/python-faq-passing/


1
变量是将名称映射到关联存储的方式,用于在程序中引用该存储位置。当您对变量进行赋值和操作时,您正在填充和更改该存储。当您重新分配变量时,您可以将其指向不同的存储位置--您正在重新映射该名称。

一些例子会很好,克里斯。 - aIKid

0

首先

"内存模型"的正式定义是描述多线程数据访问行为的说明,详见内存模型

数据模型

根据您的描述,您想要表达的实际上是"数据模型",详见Python数据模型

让我来尝试总结一下:

  1. 在Python中,数据是由object表示的。
  2. 每个object有三个关键概念:identitytypevalue
    1. identity:值不会改变,用id()函数来检查对象的id。在CPython中,id是对象的内存地址。
    2. type:对象的类型,如int/ string/ list等。永远不会改变。使用type()进行检查。
    3. value:对象的值。例如,对于一个字符串对象,它的值是“some string”,并且它是不可变的。
  3. 变量只是一个指向对象的符号。

你的问题

当键入x=5时会发生什么?

  1. 创建(或重用)一个类型为 int,值为 5 的 object 对象。
  2. 创建一个名为 x 的 variable 变量来引用该对象。此对象的引用计数器将增加 1。

就这些。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接