对于语句 x=5
,有几个事情要处理:
5
的int对象(如果已存在,则找到该对象);x
(或取消上次标记为“x”的对象关联);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
时会发生两个不同的过程:
变量
没有像在C语言中那样被广泛使用。我认为更好的方式是将其视为对象的名称或标签。对象可以存在于云端、内存、磁盘上,也可以是待生成的对象等。 - dawg在内存中有一个空间存储值。这些内存通过地址定位,通常呈十六进制或二进制数字表示。对于程序员来说,这些数字难以记忆,因此他们使用术语“变量”以一种简单的方式引用该内存位置,或者可以说是更高的抽象层次。因此,x只是一个名称,指向内存中包含值5的某个位置。就是这样!
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]
"内存模型"的正式定义是描述多线程数据访问行为的说明,详见内存模型。
根据您的描述,您想要表达的实际上是"数据模型",详见Python数据模型。
让我来尝试总结一下:
object
表示的。object
有三个关键概念:identity
、type
和value
。
identity
:值不会改变,用id()
函数来检查对象的id。在CPython中,id是对象的内存地址。type
:对象的类型,如int/ string/ list等。永远不会改变。使用type()
进行检查。value
:对象的值。例如,对于一个字符串对象,它的值是“some string”,并且它是不可变的。当键入x=5
时会发生什么?
就这些。