Observations on the three pillars of Python execution

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Aug 5 16:36:16 CEST 2011


Eric Snow wrote:

> In Python, three types of objects have special syntax and mechanics
> for their instantiation, during which a code object is generated:
> modules, classes, and functions.  

I believe you are labouring under a misapprehension. Modules and classes
don't generate code objects.

The simplest possible module just has a name:

>>> import sys
>>> module = type(sys)
>>> module("name")
<module 'name' (built-in)>

Or if you prefer to do it the "normal" way by importing from source code,
the simplest source code of all is just an empty file.

A module is an object with a __dict__, a __name__, and a __docstring__ which
defaults to None. That's it. No code objects, unless you populate the
__dict__ with functions, but it is the *functions* that have the code
objects, not the module itself. The module is just a container.

Classes are similar. The simplest class:

class K:
    pass

or if you prefer:

>>> type('K', (), {})
<class '__main__.K'>


Again, no code objects unless you populate the dict with functions (which
get turned into methods). Again, the class object is just a container. A
more complex container than modules, with a richer set of inherited
behaviour, but still just a container.

The signature for creating a function is very different:

help(type(lambda: None)) => 

class function(object)
 |  function(code, globals[, name[, argdefs[, closure]]])
 |
 |  Create a function object from a code object and a dictionary.
 |  The optional name string overrides the name from the code object.
 |  The optional argdefs tuple specifies the default argument values.
 |  The optional closure tuple supplies the bindings for free variables.


The simplest function I can think of:

>>> co = compile('pass', '', 'single')
>>> f = type(lambda: None)(co, {})

Even simpler than

def f():
    pass

Can you see why?

If you inspect a function object, you will see that it always has a code
object, even if the code object does nothing but return None:

>>> import dis
>>> dis.dis(f.func_code)
  1           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE


There may be some other obscure built-in type that includes code objects,
but I can't imagine what it would be. I feel confident in saying that
functions, and functions alone, contain code. Even methods are just
wrappers around functions. Even built-in functions like len don't contain
code! (Or at least, their code isn't accessible from Python.) Which makes
sense, if you think about it: their code is part of the Python virtual
machine, not the object.


-- 
Steven




More information about the Python-list mailing list