Python的code.interact中的变量和别名

时间:2013-06-25 22:08:55

标签: python

这种行为让我感到困惑:

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()函数,它们都在同一个内存地址。

3 个答案:

答案 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本身的内存地址(毕竟,它只是字典中的一个键)。