您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python3的多个赋值和内存地址

Python3的多个赋值和内存地址

这是由于字节码编译器中的不断折叠优化。当字节码编译器编译一批语句时,它使用字典来跟踪所看到的常量。该字典自动合并所有等效常量。

这是负责记录和编号常量(以及一些相关职责)的例程:

static int
compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
{
    PyObject *t, *v;
    Py_ssize_t arg;

    t = _PyCode_ConstantKey(o);
    if (t == NULL)
        return -1;

    v = PyDict_GetItem(dict, t);
    if (!v) {
        arg = PyDict_Size(dict);
        v = PyInt_FromLong(arg);
        if (!v) {
            Py_DECREF(t);
            return -1;
        }
        if (PyDict_SetItem(dict, t, v) < 0) {
            Py_DECREF(t);
            Py_DECREF(v);
            return -1;
        }
        Py_DECREF(v);
    }
    else
        arg = PyInt_AsLong(v);
    Py_DECREF(t);
    return arg;
}

您会看到,如果找不到已经存在的等效常量,它只会添加一个新条目并分配一个新数字。(该_PyCode_ConstantKey位确保喜欢的东西0.0-0.0以及0被认为是不等价的。)

在交互模式下,每次解释器必须实际运行您的命令时,批处理都会结束,因此在命令之间通常不会发生常量折叠:

>>> a = 1000
>>> b = 1000
>>> a is b
False
>>> a = 1000; b = 1000 # 1 batch
>>> a is b
True

在脚本中,所有顶级语句都是一批,因此发生了更多的恒定折叠

a = 257
b = 257
print a is b

在脚本中,将打印True

函数代码函数外部的代码分开跟踪其常量,这限制了常量折叠:

a = 257

def f():
    b = 257
    print a is b

f()

即使在脚本中也会打印出来False

python 2022/1/1 18:40:02 有263人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶