Why does a class’ body get executed at definition time?

Everything is executed at the module level when Python first imports a module. Function bodies (and generator expression bodies) are the exception here, not the rule. Python executes everything to create the objects contained in a module; like everything in Python, classes are objects, and so are functions.

The only reason a class body uses a separate code object is because a class body is executed in a separate namespace, with that namespace then forming the class attributes. Class bodies are not the only such namespaces; set and dict comprehensions, and in Python 3, list comprehensions are also executed with a separate namespace, scoping their locals.

So functions and generator expressions are the exception, expressly because their whole purpose is to be executed at a later time. Note that the function definition is executed:

>>> import dis
>>> dis.dis(compile('def foo(): pass', '<stdin>', 'exec'))
  1           0 LOAD_CONST               0 (<code object foo at 0x106aef2b0, file "<stdin>", line 1>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (foo)
              9 LOAD_CONST               1 (None)
             12 RETURN_VALUE        

The MAKE_FUNCTION bytecode there creates the function object, together with the stored bytecode for that function, and the result is bound to the global name foo.

Class objects are no different here; the class statement produces a class object, and as part of that object, we need to know the attributes from the class body.

If Python did not execute the class body, other code could not make any use of those class members. You couldn’t access class attributes (including class methods and static methods), you couldn’t set class attributes, etc.

Any functions that are part of the class body are of course not executed at that time. Just like top-level functions, only a MAKE_FUNCTION bytecode is executed and the resulting local name (set with STORE_FAST) is then turned into a class attribute, analogous to a global function object being bound to a global with STORE_NAME.

Leave a Comment