pythonvariables是指针?

就我所知,Python中的variables只是指针。

基于这个规则,我可以假设这个代码片段的结果:

i = 5 j = i j = 3 print(i) 

会是3 。 但是我得到了意想不到的结果,那是5

此外,我的Python书籍涵盖了这个例子:

 i = [1,2,3] j = i i[0] = 5 print(j) 

结果会是[5,2,3]

我是什么理解错误?

我们称他们为参考。 他们这样工作

 i = 5 # create int(5) instance, bind it to i j = i # bind j to the same int as i j = 3 # create int(3) instance, bind it to j print i # i still bound to the int(5), j bound to the int(3) 

小的整数被实施,但这对于这个解释并不重要

 i = [1,2,3] # create the list instance, and bind it to i j = i # bind j to the same list as i i[0] = 5 # change the first item of i print j # j is still bound to the same list as i 

variables不是指针。 当你分配给一个variables时,你将把这个名字绑定到一个对象上。 从这一点起,您可以使用名称来引用对象,直到该名称被反弹。

在你的第一个例子中,名字i被绑定到值5 。 将不同的值绑定到名称ji没有任何影响,所以当您稍后打印i的值时,值仍然是5

在你的第二个例子中,你将ij绑定到同一个列表对象。 当您修改列表的内容时,无论使用哪个名称来引用列表,都可以看到更改。

请注意,如果你说“两个列表已经改变”,这将是不正确的。 只有一个列表,但它有两个名称( ij )引用它。

相关文档

  • 执行模型 – 命名和绑定

Pythonvariables是绑定到对象的名字

从文档 :

名称是指对象。 名称是通过名称绑定操作引入的。 程序文本中名称的每一次出现都是指在包含该用途的最内层function块中build立的该名称的绑定

当你这样做

 i = 5 j = i 

这和做一样:

 i = 5 j = 5 

j不指向i ,而且在赋值之后, j不知道i存在。 j只是绑定到i在分配时指出的任何东西。

如果你在同一行上做了分配,它看起来像这样:

 i = j = 5 

结果是完全一样的。

因此,稍后再做

 i = 3 

不会改变j指向的东西 – 你可以交换它 – j = 3不会改变i指向的东西。

你的例子不解引用列表

所以当你这样做的时候:

 i = [1,2,3] j = i 

这和做这个一样:

 i = j = [1,2,3] 

所以ij都指向相同的名单。 然后你的例子改变列表:

 i[0] = 5 

Python列表是可变对象,所以当您从一个引用中更改列表,并且从另一个引用查看它时,您将看到相同的结果,因为它是相同的列表。

它们不是十分指针,它们是对象的引用。 对象可以是可变的,也可以是不可变的。 不可变对象在被修改时被复制。 一个可变对象被原地改变。 一个整数是一个不可变的对象,通过你的i和jvariables来引用。 列表是一个可变的对象。

在你的第一个例子

 i=5 # The label i now references 5 j=i # The label j now references what i references j=3 # The label j now references 3 print i # i still references 5 

在你的第二个例子中:

 i=[1,2,3] # i references a list object (a mutable object) j=i # j now references the same object as i (they reference the same mutable object) i[0]=5 # sets first element of references object to 5 print j # prints the list object that j references. It's the same one as i. 

当你设置j=3 ,标签j不再适用于(点)到i ,它开始指向整数3i的名字仍然是指你最初设定的价值, 5

赋值不会修改对象; 它所做的只是改变variables的地方。 改变一个variables点的位置在另一个点的位置不会改变。

您可能正在考虑数组和字典是可变types的事实。 有些操作员可以在现场修改实际的对象,如果你使用其中的一个,你会看到所有variables指向同一个对象的变化:

 x = [] y = x x.append(1) # x and y both are now [1] 

但分配仍然只是移动指针:

 x = [2] # x is now [2], y is still [1] 

数字是值types,这意味着实际值是不可变的。 如果你做x=3; x += 2 x=3; x += 2 ,你不是把数字3变成数字5; 你只是让x指向5而不是3. 3仍然没有变化,任何指向它的variables仍然会看到3作为它们的值。

(在实际的实现中,数字可能不是引用types,variables实际上包含值的表示而不是直接指向它,但是这种区别不会改变值types所关心的语义)。

在Python中,一切都是对象,包括返回的内存块。 这意味着,当新的内存块被创build(不pipe你创build了什么:int,str,自定义对象等),你有一个新的内存对象。 在你的情况下,这是创build一个新的(内存)对象,因此有一个新的地址的分配。

如果你运行以下,你可以很容易地看到我的意思。

 i = 5 j = i print("id of j: {}", id(j)) j = 3 print("id of j: {}", id(j)) 

海事组织,内存明智,这是C和Python之间的关键理解/差异。 在C / C ++中,返回一个内存指针(当然,如果你使用指针语法的话),而不是一个内存对象,这使得在改变引用地址方面给你更多的灵活性。

'='符号左侧的variables是'='右侧的值,

i = 5

j = i — j有5

j = 3 — j有3(覆盖5的值),但是没有任何改变

print(i) – 所以这打印5