网络中的python名称存在很多混淆,文档似乎没有明确的名称。以下是我读过的关于python名称的几件事。
名称是对象的引用(它们在哪里?堆?),名称包含的是一个地址。 (比如Java)。
python中的名称类似于C ++引用(int& b),这意味着它是内存位置的另一个别名;即对于int a
,a
是一个记忆位置。如果int& b = a
表示b
是同一内存位置的另一个名称
名称与C中自动取消引用的指针变量非常相似。
上述哪一项陈述是正确的?
Python名称中是否包含某种地址,或者它只是内存位置的名称(如C ++ &
引用)?
存储python名称的位置,堆栈还是堆?
EDIT
:
每当一个(可能是合格的)名称出现在赋值的右侧,或者单独出现在一行上时,该名称将被取消引用到该对象本身。如果某个名称未绑定在某个可访问的范围内,则无法取消引用该名称;尝试这样做会引发NameError异常。如果名称后跟左右括号(可能在它们之间使用逗号分隔的表达式),则在取消引用后调用/调用该对象。对于Python对象,可以控制和覆盖调用时发生的事情。但一般来说,调用函数或方法会运行一些代码,而调用类会创建一个实例。例如:
pkg.subpkg.func()#从名称空间
调用函数x = y#deref'y'并将同一对象绑定到'x'
这是有道理的。只想交叉检查它是多么真实。请评论和答案
答案 0 :(得分:4)
名称是对象的引用
是。如果你只想了解Python变量的语义,你不应该关心对象的位置;它们位于内存中,Python实现为您管理内存。他们如何做到这一点取决于实现(CPython,Jython,PyPy ......)。
python中的名称类似于C ++引用
不完全是。在C ++中重新分配引用实际上会重新分配引用的内存位置,例如之后
int i = 0;
int &r = i;
r = 1;
i == 1
确实如此。除非使用可变容器对象,否则不能在Python中执行此操作。您可以获得最接近C ++引用行为的是
i = [0] # single-element list
r = i # r is now another reference to the object referenced by i
r[0] = 1 # sets i[0]
与C
中自动解引用的指针变量非常相似
不,因为那时它们与上述方面的C ++引用类似。
Python名称中是否包含某种地址,还是只是内存位置的名称?
前者更接近事实,假设一个简单的实现(再次,PyPy可能做的事情与CPython不同)。在任何情况下,Python变量都不是存储位置,而是可能存在于内存中任何位置的对象的标签/名称。
Python进程中的每个对象都有一个标识,可以使用id
函数获取,该函数在CPython中返回其内存地址。您可以通过使用id
检查is
或更多直接来检查两个变量(或更常见的表达式)是否引用同一个对象:
>>> i = [1, 2]
>>> j = i # a new reference
>>> i is j # same identity?
True
>>> j = [1, 2] # a new list
>>> i == j # same value?
True
>>> i is j # same identity?
False
答案 1 :(得分:2)
Python名称就是名字。你有对象和名字,就是这样。
创建一个对象,比如[3, 4, 5]
在堆上创建对象某处。你不需要知道如何。现在,您可以将名称命名为此对象,方法是将其分配给名称:
x = [3, 4, 5]
也就是说,赋值运算符分配名称而不是值。 x
不是 [3, 4, 5]
,不,它只是一个指向[3, 4, 5]
对象的名称。所以这样做:
x = 1
不会更改原始[3, 4, 5]
对象,而是将对象1
分配给名称x。另请注意,大多数表达式(如[3, 4, 5]
)以及8 + 3
都可以创建临时表达式。除非你为该临时名称指定名称,否则它将立即死亡。没有(除了,例如在CPython中用于小数字,但除此之外)保持未被引用的对象活动并缓存它们的机制。例如,这失败了:
>>> x = [3, 4, 5]
>>> x is [3, 4, 5] # must be some object, right? no!
False
但是,这只是赋值(在Python中不可重载)。事实上,Python中的对象和名称表现得像是自动解除引用指针,除了它们被自动引用计数并且在它们不被引用之后死掉(至少在CPython中)并且它们不会在赋值时自动取消引用。 / p>
由于这种内存模型,例如C ++重载索引操作的方法不起作用。相反,Python使用__setitem__
和__getitem__
,因为您无法返回任何“可分配”的内容。此外,运营商+=
,*=
等......通过创建临时工具并将该临时工具分配回名称来工作。
答案 2 :(得分:1)
Python对象为stored on a heap,并通过reference counting进行垃圾回收。
变量是对Java中对象的引用,因此适用第1点。我不熟悉C ++中的C ++或自动解引用的指针变量,以便对它们进行调用。
最终,它是python解释器,它在解释器结构中查找项目,通常是python列表和字典以及其他这样的抽象容器;例如,命名空间使用dict
(哈希表),其中名称和值是指向其他python对象的指针。这些由mapping protocol明确管理。
对于python程序员来说,这一切都是隐藏的;你不需要知道你的对象住在哪里,只要你有一些引用它们的东西它们仍然存在。在python中编码时传递这些引用。