变量名称如何在内部存储和映射? [英] How are variables names stored and mapped internally?

查看:92
本文介绍了变量名称如何在内部存储和映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了 https://stackoverflow.com/a/19721096/1661745 ,似乎在CPython中,变量只是与引用关联的名称。

I read https://stackoverflow.com/a/19721096/1661745 and it seems that in CPython, variables are simply names that are associated with references.


语句x = 5发生了几件事:

There are several things going on with the statement x=5:


  1. 创建一个值为5的int对象(或找到它是否已经存在

  2. 创建名称x(或与x取消关联)最后一个对象
    'x'标记)

  3. 对新的(或找到的)int对象的引用计数是
    加1

  4. 名称x与创建(或找到)的
    值为'5'的对象相关。

  1. an int object with the value of 5 is created (or found if it already exists)
  2. the name x is created (or disassociated with the last object 'x' labeled)
  3. the reference count to the new (or found) int object is increased by 1
  4. the name x is associated with the object with the value '5' created (or found).


但是,我仍然不清楚到底如何在内部实现变量。

However, I'm still not clear with exactly how variables are implemented internally.

即:



  1. 名称x已创建(或与最后一个标记为'x'的对象无关);


那么这个名称也不会占用内存空间吗? sys.sizeof(x)等于 sys.sizeof(5),我得到了 sys.sizeof(x)只能返回关联引用的大小,但是名称 x 的大小是多少?

Then wouldn't the name also take up memory space? sys.sizeof(x) equals sys.sizeof(5), and I get that sys.sizeof(x) could only return the size of the associated reference, but then what is the size of the name x?



  1. 名称x与创建(或找到)值为'5'的对象相关联


内部如何实现?我认为可以使用 dict 来完成,其中键是变量名( str ? ),该值是与之关联的引用。

How is this implemented internally? I think at a high level it can be done with a dict, where the key is the variable name (str?) and the value is the reference that it's associated with.

推荐答案


可以使用dict完成操作,其中键是变量名(str?),值是它与之关联的引用。

I think at a high level it can be done with a dict, where the key is the variable name (str?) and the value is the reference that it's associated with.

这也是它内部的工作方式。在CPython中,变量名和它们指向的对象通常存储在Python字典中。

This is how it works internally too. In CPython, variable names and the objects they point to are typically stored in a Python dictionary; the very same data structure that you can use when writing Python code.

当您编写 x = 5 时,将使用相同的数据结构。名称 x 设置为全局名称词典中的键,相应的值为5。您可以使用 globals()函数返回并检查该字典,该函数给出当前作用域的命名空间的内容。

When you write x = 5, the name x is set as a key in the dictionary of global names with 5 as the corresponding value. You can return and inspect this dictionary using the globals() function, which gives the contents of the current scope's namespace.

所以您也正确地认为名称 x 占用了空间。它以字符串形式存在于内存中,Python会为字典的键保留对它的引用。

So you're also correct that the name x takes up space. It exists as a string somewhere in memory and Python keeps a reference to it for the key of the dictionary.

如果您想更深入地了解CPython源代码以查看位置 x 被赋值为5,您可以查看ceval.c。编写 x = 5 会触发 LOAD_CONST 操作码(将整数5放入堆栈)以及 STORE_GLOBAL 操作码*(将名称 x 设置为字典中的键,其值为5)。

If you want to peer deeper into the CPython source to see where x gets assigned to the value 5, you could have a look at ceval.c. Writing x = 5 triggers the LOAD_CONST opcode (to put the integer 5 onto the stack) and also the STORE_GLOBAL opcode* (to set the name x as a key in the dictionary with 5 as the value).

以下 STORE_GLOBAL 操作码的代码:

TARGET(STORE_GLOBAL) {
    PyObject *name = GETITEM(names, oparg);
    PyObject *v = POP();
    int err;
    err = PyDict_SetItem(f->f_globals, name, v);
    Py_DECREF(v);
    if (err != 0)
        goto error;
    DISPATCH();
}

您可以看到对 PyDict_SetItem 更新globals字典。

You can see the call to PyDict_SetItem to update the globals dictionary.

*如果您检查生成的字节码x = 5 (例如,使用 dis ),您可能会看到 STORE_NAME 操作码。此操作码的功能相同(请参见此处简要说明)。

* If you inspect the bytecode generated by x = 5 (e.g. using dis) you might see the STORE_NAME opcode used. This opcode functions in the same way (see here for a brief description).

这篇关于变量名称如何在内部存储和映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆