什么是 co_names?
What is co_names?
检查模块中 co_names
的 description 读取:
tuple of names of local variables
然而实际上 co_names
是全局变量名的元组,而 co_varnames
是局部变量名(和参数名)的元组。例如:
a = 1
def f(b):
c = a + b
print(f.__code__.co_varnames) # prints ('b', 'c')
print(f.__code__.co_names) # prints ('a',)
此外,在 dis
模块的文档中,许多指令描述暗示 co_names
包含全局变量的名称。例如 LOAD_GLOBAL
description 显示为:
Loads the global named co_names[namei] onto the stack.
我是不是误会了什么? co_names
真的包含"names of local variables"吗?
编辑 2017 年 7 月 17 日
如 comments/answers 中所述,这似乎是文档错误。已提交错误问题 here。
编辑 2017 年 7 月 22 日
Pull request 修复此文档错误已批准并等待合并。
正如其他人已经说过的,这似乎是文档错误。 documentation for code objects clearly contradicts the documentation for inspect
:
co_varnames
is a tuple containing the names of the local variables (starting with the argument names); [...] co_names
is a tuple containing the names used by the bytecode;
此外,访问代码对象的属性 co_names
和 co_varnames
与 inspect
中所述冲突:
>>> def f():
... a = 1
... b = 2
...
>>> f.__code__.co_names
()
>>> f.__code__.co_varnames
('a', 'b')
此外,CPython's compiler 源代码中的注释明确提到 co_varnames
用于局部变量:
PyObject *u_names; /* all names */
PyObject *u_varnames; /* local variables */
您看不到 co_varnames
的原因是因为上面的代码正在为 Python 用于编译代码的 编译器对象 初始化属性。 u_names
and u_varnames
are both later passed into PyCode_New
- CPython 代码对象的构造函数:
names = dict_keys_inorder(c->u->u_names, 0);
varnames = dict_keys_inorder(c->u->u_varnames, 0);
...
co = PyCode_New(..., names, varnames, ... );
和PyCode_New
assigns names
and varnames
to the co_names
and co_varnames
attributes respectively:
Py_INCREF(names);
co->co_names = names;
Py_INCREF(varnames);
co->co_varnames = varnames;
如果您还没有,我建议在 bugs.python.org 填写错误报告,让 Python 开发团队了解文档中的这种不一致之处。
检查模块中 co_names
的 description 读取:
tuple of names of local variables
然而实际上 co_names
是全局变量名的元组,而 co_varnames
是局部变量名(和参数名)的元组。例如:
a = 1
def f(b):
c = a + b
print(f.__code__.co_varnames) # prints ('b', 'c')
print(f.__code__.co_names) # prints ('a',)
此外,在 dis
模块的文档中,许多指令描述暗示 co_names
包含全局变量的名称。例如 LOAD_GLOBAL
description 显示为:
Loads the global named co_names[namei] onto the stack.
我是不是误会了什么? co_names
真的包含"names of local variables"吗?
编辑 2017 年 7 月 17 日
如 comments/answers 中所述,这似乎是文档错误。已提交错误问题 here。
编辑 2017 年 7 月 22 日
Pull request 修复此文档错误已批准并等待合并。
正如其他人已经说过的,这似乎是文档错误。 documentation for code objects clearly contradicts the documentation for inspect
:
co_varnames
is a tuple containing the names of the local variables (starting with the argument names); [...]co_names
is a tuple containing the names used by the bytecode;
此外,访问代码对象的属性 co_names
和 co_varnames
与 inspect
中所述冲突:
>>> def f():
... a = 1
... b = 2
...
>>> f.__code__.co_names
()
>>> f.__code__.co_varnames
('a', 'b')
此外,CPython's compiler 源代码中的注释明确提到 co_varnames
用于局部变量:
PyObject *u_names; /* all names */
PyObject *u_varnames; /* local variables */
您看不到 co_varnames
的原因是因为上面的代码正在为 Python 用于编译代码的 编译器对象 初始化属性。 u_names
and u_varnames
are both later passed into PyCode_New
- CPython 代码对象的构造函数:
names = dict_keys_inorder(c->u->u_names, 0);
varnames = dict_keys_inorder(c->u->u_varnames, 0);
...
co = PyCode_New(..., names, varnames, ... );
和PyCode_New
assigns names
and varnames
to the co_names
and co_varnames
attributes respectively:
Py_INCREF(names);
co->co_names = names;
Py_INCREF(varnames);
co->co_varnames = varnames;
如果您还没有,我建议在 bugs.python.org 填写错误报告,让 Python 开发团队了解文档中的这种不一致之处。