Observations on the three pillars of Python execution

Eric Snow ericsnowcurrently at gmail.com
Fri Aug 5 12:46:02 EDT 2011


On Fri, Aug 5, 2011 at 8:36 AM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> 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.

Sorry for any confusion.  I was talking specifically about the their
instantiation through their respective special syntax.  During that
process a code object is generated for each.  For classes and modules
the code object is executed and then discarded.  I covered this
explicitly in one of the observations.

>
> 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.

Agreed that [non-builtin] functions are the only objects that have a
code object attribute.  However, they are not the only objects for
which a code object is generated and executed.

I've always found your frequent responses very insightful and
thoughtful, Steven, and I appreciate that.  In this case I can only
imagine that my opening statement was unclear enough that you did not
continue to read the rest, where the context of my point was more
clear (I hope :).  Regardless, thanks for taking a look.

-eric

>
>
> --
> Steven
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list