New to the series? The previous entry was part 3.
Okay, so we've seen a fair amount of bytecode already. We know how modules, classes and functions work and today we'll study an example where it all comes together. It's more about consolidating our insights rather than learning new material.
A simple module
Right as you see this code you'll be thinking in bytecode already. We have three top level bindings:
- pencils is bound to the integer 13
- give_back is bound to a function object
- Person is bound to a class object
pencils = 13 def give_back(x): return x class Person(object): default_age = 7 def __init__(self, age): self.age = age or self.default_age def had_birthday(self): self.age += 1 def how_old(self): return self.age
Let's disassemble this module so we can complete the picture. Ned Batchelder was kind enough to provide some example code for this purpose.
We won't go through all of the bytecode, as it's a bit long. But this diagram illustrates some of the key components of this module. On display we have:
- The module mod.py's code object. Two of its constants are code objects too:
- The function give_back's code object.
- The class Person's code object. it has three constants that are code objects, one of which is:
- The method how_old's code object.
So yes, a
.pyc file simply contains a code object (of type
types.CodeType), which has a bunch of attributes. Not all of those attributes will be set - it depends on what kind of functional object (module, class, function, ...) the code operates on.
A function that uses local variables will store them in
A class or a function will have a
Many code objects will have
.co_filename value that tells you where its source code comes from.
And in many cases a code object will have other code objects in its
.co_consts tuple, and those will be code objects representing classes or functions or what have you.