【问题标题】:Assignment of a variable变量的赋值
【发布时间】:2016-09-21 00:17:36
【问题描述】:

我对 python 中的变量赋值问题感到困惑。我试着在网上找了pages关于this issue,但我还是不明白。

假设我为变量分配了某个值:

v = 2

Python 在某个内存位置保留了一个位置,其值为2。我们现在知道如何通过为它分配一个变量名来访问那个特定的内存位置:v

如果是这样,我们这样做:

v = v + 4

将使用值6 (2+4) 归档一个新的内存位置,所以现在要访问这个值,我们将变量v 绑定到它。

这是正确的,还是完全不正确的?

内存位置中的初始值2 会发生什么?它不再绑定到任何变量,所以不能再访问这个值了?这是否意味着在接下来的几分钟内,这个内存位置将被垃圾收集器释放?

感谢您的回复。

编辑:

v = 2v = v + 2 只是简单的示例。在我的例子中,我有一个非 python 原生对象,而不是 2 和 v+2,它的重量可以从几十兆字节到 400 兆字节不等。 我很抱歉没有在一开始就解决这个问题。我不知道整数和其他类型的对象有区别。

【问题讨论】:

    标签: python variables variable-assignment


    【解决方案1】:

    就这一点而言,你是对的。实际上,发生的事情是 Python 构造了整数对象 24。在第一个赋值中,解释器使 v 指向 2 对象。

    在第二个任务中,我们构造了一个对象 6 并让 v 指向它,正如您所怀疑的那样。

    接下来会发生什么取决于实施。大多数将对象用于原子值的解释器和编译器会将 2 对象识别为一个小整数,可能会再次使用,并且维护起来非常便宜——因此不会被收集。一般情况下,代码中出现的字面量不会被转为垃圾回收。


    感谢您更新问题。是的,你的大对象,没有对它的引用,现在可用于 GC。

    【讨论】:

    • “大多数这种类型的解释器和编译器”是什么意思?问题特别是关于 Python,据我所知它没有垃圾收集器
    • 好点......虽然垃圾收集取决于实现。我们有一个可以回收释放的内存;否则我们的一些大数据应用程序会出错。
    • 谢谢@Prune 和@maxymoo。为什么维基百科页面上关于分配的内容如下:assignment statement ... copies a value into the variable.。赋值是否真的将值复制到变量中?或者它实际上只是指向那个值(在内存位置)?这两个是不同的东西。这是链接:https://en.wikipedia.org/wiki/Assignment_%28computer_science%29
    • 维基百科页面对许多编程语言都是通用的。在 Python 中,复制的值是指向 2 的指针,而不是 2 本身。这是语言定义的一个重要细节。在大多数语言中,实际值被复制到变量的内存位置。 Python 的优势在于 每个 变量的主要位置的大小是一个内存字。
    • 谢谢。那么当 Python 将指针复制到内存位置中的某个对象时,该对象的大小是无关紧要的吗?它可以是1kb或1gb,是一样的吗?指针的复制会以同样的速度“完成”吗?
    【解决方案2】:

    带有小整数(-5 到 256)的示例并不是最好的示例,因为它们以特殊的方式表示(例如,参见 this)。

    你对事物的流程通常是正确的,所以如果你有类似的东西

    v = f(v)
    

    会发生以下情况:

    • 评估f(v)(取模小整数或文字优化)的结果创建了一个新对象
    • 这个新对象绑定到变​​量v
    • 以前在 v 中的任何内容现在都无法访问,而且通常很快就会被垃圾回收

    【讨论】:

    • 谢谢@aldanor。在不需要使用 v = v + someValue 时使用它是一种不好的做法吗?例如,我可以这样写:v2 = v + someValue。但是从垃圾回收的角度来看,如果我将右侧的表达式分配给先前定义的变量(在这种情况下为v)会更好,即使我不必这样做?
    • 这并不是一个坏习惯,除非名称阴影引入了不必要的混淆(例如,分配给与函数参数名称冲突的名称)。在大多数情况下,这两个示例之间没有区别,因为垃圾收集不会立即发生,而且很可能在它发生时,v 会以任何一种方式被收集。我从来没有亲眼目睹过这种事情很重要的例子,所以除非你正在处理回收成本很高的巨大物体,否则你不应该真正担心它。
    • 明白。我认为通过引入v = v +someValue 可以以某种方式节省内存空间。正如我现在看到的那样,情况并非如此,并且可能会引起混淆,因此我不会使用这种语法。感谢@aldanor 的帮助。
    猜你喜欢
    • 2020-02-21
    • 2015-05-18
    • 2016-03-26
    • 2021-12-04
    • 2011-05-29
    • 2015-09-19
    • 1970-01-01
    相关资源
    最近更新 更多