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
。 将不同的值绑定到名称j
对i
没有任何影响,所以当您稍后打印i
的值时,值仍然是5
。
在你的第二个例子中,你将i
和j
绑定到同一个列表对象。 当您修改列表的内容时,无论使用哪个名称来引用列表,都可以看到更改。
请注意,如果你说“两个列表已经改变”,这将是不正确的。 只有一个列表,但它有两个名称( i
和j
)引用它。
相关文档
- 执行模型 – 命名和绑定
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]
所以i
和j
都指向相同的名单。 然后你的例子改变列表:
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
,它开始指向整数3
。 i
的名字仍然是指你最初设定的价值, 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