python variables are pointers?
据我所知,python中的变量只是指针。
基于此规则,我可以假设此代码段的结果:
1 2 3 4 | i = 5 j = i j = 3 print(i) |
可能是
此外,我的python书确实涵盖了以下示例:
1 2 3 4 | i = [1,2,3] j = i i[0] = 5 print(j) |
结果将是
我理解错了什么?
我们称之为参考文献。他们是这样工作的
1 2 3 4 | 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) |
小整数被拘留,但这对这个解释并不重要。
1 2 3 4 | 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 |
变量不是指针。当您分配给一个变量时,您正在将名称绑定到一个对象。从这一点开始,您可以通过使用名称来引用对象,直到该名称被反弹为止。
在第一个示例中,名称
在第二个示例中,您将
请注意,如果您说"两个列表都已更改",则是不正确的。只有一个列表,但它有两个名称(
相关文件
- 执行模型-命名和绑定
python变量是绑定到对象的名称
来自文档:
Names refer to objects. Names are introduced by name binding operations. Each occurrence of a name in the program text refers to the binding of that name established in the innermost function block containing the use.
当你这样做的时候
1 2 | i = 5 j = i |
就像这样:
1 2 | i = 5 j = 5 |
如果您在同一行上执行了任务,则如下所示:
1 | i = j = 5 |
结果完全一样。
因此,以后做
1 | i = 3 |
不改变
所以当你这样做的时候:
1 2 | i = [1,2,3] j = i |
就像这样:
1 | i = j = [1,2,3] |
因此,
1 | i[0] = 5 |
python列表是可变的对象,所以当您从一个引用中更改列表,并从另一个引用中查看它时,您将看到相同的结果,因为它是相同的列表。
它们不是很好的指针,它们是对对象的引用。对象可以是可变的,也可以是不可变的。不可变对象在修改时被复制。一个可变的物体被改变了位置。整数是不可变的对象,由I和J变量引用。列表是可变对象。
在第一个例子中
1 2 3 4 5 6 7 8 | 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 |
在第二个示例中:
1 2 3 4 5 6 7 8 | 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. |
"="符号左侧的Ever变量与"="符号右侧的值一起赋值。
赋值不会修改对象;它所做的只是更改变量点的位置。改变一个变量点的位置不会改变另一个变量点的位置。
您可能会想到数组和字典是可变类型。有一些运算符可以在适当的位置修改实际对象,如果使用其中一个,则可以看到指向同一对象的所有变量的变化:
1 2 3 4 | x = [] y = x x.append(1) # x and y both are now [1] |
但分配仍然只是移动指针:
1 2 | x = [2] # x is now [2], y is still [1] |
数字是值类型,这意味着实际值是不可变的。如果你做了
(在实际的实现中,数字可能不是引用类型,变量实际上包含值的直接表示,而不是指向它,但是这种区别不会改变涉及值类型的语义。)
当设置
在Python中,一切都是对象,包括返回的内存片段本身。这意味着,当创建新的内存块时(不管您创建了什么:int、str、custom对象等),都会有一个新的内存对象。在您的例子中,这是对3的赋值,它创建一个新的(内存)对象,从而有一个新的地址。
如果你运行下面的程序,你会很容易明白我的意思。
1 2 3 4 5 | i = 5 j = i print("id of j: {}", id(j)) j = 3 print("id of j: {}", id(j)) |
在内存方面,这是C和Python之间的关键理解/区别。在C/C++中,返回一个内存指针(如果你使用指针语法当然是),而不是内存对象,这会给你在更改引用地址方面提供更多的灵活性。