inspect模块中co_names
的description为:
局部变量名称的
元组
然而,在实践中,看起来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为:
将全局命名的co_namesnamei加载到堆栈上。
我是不是误解了什么?co_names
真的包含“局部变量的名称”吗?
编辑2017年7月17日
正如在注释/答案中提到的,这似乎是一个文档错误。错误问题归档为here。
编辑2017年7月22日
用于修复此文档错误的Pull request,该错误已批准并等待合并。
发布于 2017-07-18 01:16:19
正如其他人已经说过的,这似乎是一个文档错误。documentation for code objects显然与documentation for inspect
相矛盾
co_varnames
是一个包含本地变量名称(以参数名称开头)的元组;...co_names
是一个包含字节码使用的名称的元组;
此外,访问代码对象的属性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开发团队知道文档中的这种不一致之处。
https://stackoverflow.com/questions/45147260
复制相似问题