这种行为让我感到困惑:
import code
class foo():
def __init__(self):
self.x = 1
def interact(self):
v = globals()
v.update(vars(self))
code.interact(local=v)
c = foo()
c.interact()
Python 2.6.6 (r266:84292, Sep 11 2012, 08:34:23)
(InteractiveConsole)
>>> id(x)
29082424
>>> id(c.x)
29082424
>>> x
1
>>> c.x
1
>>> x=2
>>> c.x
1
为什么'c.x'的行为不像'x'的别名?如果我正确理解id()函数,它们都在同一个内存地址。
答案 0 :(得分:3)
从-5到256的小整数在python中缓存,即它们的id()
总是相同的。
来自docs:
当前实现为所有实体保留了一个整数对象数组 -5到256之间的整数,当你在该范围内创建一个int时 实际上只是返回对现有对象的引用。
>>> x = 1
>>> y = 1 #same id() here as integer 1 is cached by python.
>>> x is y
True
如果两个标识符返回 id()的相同值,那么这并不意味着它们可以作为别名 彼此,它完全取决于他们指向的对象的类型。
对于不可变对象,您无法在python中创建别名。修改对不可变对象的引用之一将简单地指向一个新对象,而对该旧对象的其他引用仍将保持不变。
>>> x = y = 300
>>> x is y # x and y point to the same object
True
>>> x += 1 # modify x
>>> x # x now points to a different object
301
>>> y #y still points to the old object
300
可变对象可以从其任何引用中修改,但这些修改必须是就地修改。
>>> x = y = []
>>> x is y
True
>>> x.append(1) # list.extend is an in-place operation
>>> y.append(2) # in-place operation
>>> x
[1, 2]
>>> y #works fine so far
[1, 2]
>>> x = x + [1] #not an in-place operation
>>> x
[1, 2, 1] #assigns a new object to x
>>> y #y still points to the same old object
[1, 2]
答案 1 :(得分:2)
如果我正确理解了id()函数,它们都在同一个内存地址。
您无法正确理解。 id
返回一个保证以下身份的整数:如果id(x) == id(y)
则保证x is y
(反之亦然)。
因此,id
告诉您变量指向的对象(值),而不是变量本身。
与内存地址的任何关系纯粹是一个实现细节。 Python,不像,例如C,不假设与底层机器有任何特定关系(无论是物理的还是虚拟的)。 python中的变量都是不透明的,并且不是语言可访问的(即不是第一类)。
答案 2 :(得分:2)
code.interact
只为你做了(有效)x=c.x
。因此,当您检查他们的id
时,他们指向完全相同的对象。但是x=2
为变量x
创建了一个新的绑定。它不是别名。据我所知,Python没有别名。
是的,在CPython中id(x)
是对象x
指向的内存地址。 不变量x
本身的内存地址(毕竟,它只是字典中的一个键)。