co_names attribute on Python code objects is
As a trap for the unwary, Python code objects have both a
co_varnames attribute. Since I just confused myself about
which was what the other day, here is what the
co_names one is.
co_names is a tuple of names of globals and attributes
that are used by the function's code. For example, if you have '
self.bar()' in the function, the '
bar' will show up in
as will the '
foo' from '
a = foo()'.
(Perhaps I should call these 'identifiers' instead of 'names'. In Ruby and Lisp and probably elsewhere these are called symbols.)
Ultimately this is part of how the CPython bytecode interpreter is
implemented. When the bytecode interpreter refers to anything but a
local variable, it has to do an attribute lookup
with the name to get the actual object involved. Rather than put the
name that's being looked up directly in the bytecode instructions,
CPython puts all the names into a table and has the instructions refer
to table slots, so the
LOAD_GLOBAL instruction says 'look up name 3'
instead of 'look up "somevar"'. And
co_names is that table (or at
least a representation of that table).
Each name only appears once in
co_names, no matter how many times
it's used in your function and no matter if it's used in different
contexts; if you have both '
obj.foo' and '
foo()' in your code, there
will only be one "foo" in
co_names, even though one use of the name
is for an object attribute and one is for a global. As far as I can tell
from reading CPython source, names are always interned strings and so
are globally unique.
co_names table slot numbers are of course a per-function thing;
slot 0 in different functions will refer to completely different names.)