Sometimes you spend enough time with a tool that you think you know it well, until something smacks you out of your arrogant stupidity back into the realm of humility. A couple of days ago, someone approached me with a grin, showing me a piece of code that looked like this (simplified):

After I got over the exec(), the actual weird thing here dawned on me. You can put a for loop inside a class body? What the hell?

So I loaded up ipython and started exploring:

OK, interesting. “x1=1” really resulted in something like “Foo.x1 = 1”. (Also “i”, the loop variable, is in there — a relatively well known quirk). So it seems like any name definitions in this zone automatically get attached to the class, just like a regular class variable definition would. Wait a second — so are method and attribute declarations within a class not special syntax?

Quoth the Python language reference:

A class definition is an executable statement.

Which sounds normal and benign enough on its own until you realize what this really entails. Further down, the reference continues:

The class’s suite is then executed in a new execution frame (see Naming and binding), using a newly created local namespace and the original global namespace. (Usually, the suite contains mostly function definitions.)

Yeah, usually. *evil chortle*

When the class’s suite finishes execution, its execution frame is discarded but its local namespace is saved. [4] A class object is then created using the inheritance list for the base classes and the saved local namespace for the attribute dictionary. The class name is bound to this class object in the original local namespace.

So yes, really, class bodies aren’t a syntactically specialized thing that can only have variable and method declarations. In comparison to other languages, for example Java, this certainly is out of the ordinary. A class body is an execution context just like any other, almost like a function body. It’s just that at the end, all the local variables in that context become your class variables. You can put anything in there!!

Of course, my first instinct is to see just how silly you can get.

Pretty silly, it turns out. One thing to note in this example is that “cats” gets printed when the class is defined, but not when a new instance is created. This makes sense — the definitions of class variables and methods (along with any other statements) are executed while the class definition is being executed, all before __init__ ever gets run. Another experiment:

OK, that was kind of pointless. To do this exploration more systematically, one can actually dig into CPython’s Grammar file, which is pleasantly short and readable. I pulled out the relevant bits here:

classdef: 'class' NAME ['(' [arglist] ')'] ':' suite suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt) stmt: simple_stmt | compound_stmt compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt

So what if …

Uhhhh, seems like it could end up being useful perhaps, but not exactly sure how, honestly, when we have “import foo as bar”. Or perhaps:

Gross, no one do that please. And yet another example:

Cool, that works. Come to think of it, I’ve seen that before — often for small enum classes and such that are only used with the larger class itself. Also, in stuff like Django ORM, with the “Meta” class.