加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python3多重赋值和内存地址

发布时间:2020-12-20 13:15:13 所属栏目:Python 来源:网络整理
导读:参见英文答案 ‘is’ operator behaves unexpectedly with non-cached integers????????????????????????????????????2个 在阅读了与我的问题非常相似的 this和 this之后,我仍然无法理解以下行为: a = 257b = 257print(a is b) #Falsea,b = 257,257print(a
参见英文答案 > ‘is’ operator behaves unexpectedly with non-cached integers????????????????????????????????????2个
在阅读了与我的问题非常相似的 this和 this之后,我仍然无法理解以下行为:

a = 257
b = 257
print(a is b) #False
a,b = 257,257
print(a is b) #True

当打印id(a)和id(b)时,我可以看到在单独的行中赋值的变量具有不同的id,而对于多个赋值,两个值具有相同的id:

a = 257
b = 257
print(id(a)) #139828809414512
print(id(b)) #139828809414224
a,257
print(id(a)) #139828809414416
print(id(b)) #139828809414416

但是,通过说多个相同值的赋值总是创建指向同一个id的指针,从而解释这种行为是不可能的:

a,b = -1000,-1000  
print(id(a)) #139828809414448
print(id(b)) #139828809414288

是否有一个明确的规则,它解释了变量何时获得相同的ID而不是?

编辑

相关信息:此问题中的代码以交互模式运行(ipython3)

解决方法

这是由于字节码编译器中的常量折叠优化.当字节码编译器编译一批语句时,它会跟踪 uses a dict跟踪它看到的常量.此dict自动合并任何等效常量.

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

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

在脚本中,所有顶级语句都是一个批处理,因此more constant folding happens:

a = 257
b = 257
print a is b

在脚本中,这将打印True.

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

a = 257

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

f()

Even in a script,这打印错误.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读