Are decorators really that different from metaclasses...

Bengt Richter bokr at
Wed Aug 25 12:08:06 CEST 2004

On Wed, 25 Aug 2004 13:26:03 +1000, Anthony Baxter <anthonybaxter at> wrote:

>I forgot one other point I meant to add - think about when the body of
>a class gets executed, vs when the body of a function gets executed.
>The former is at compile time, the latter is when the function is
Actually, the body of the class gets executed after whatever code
just precedes the class def (though with a different environment, with
bindings going into the class dict), but UIAM both of those are compiled
when the combined source is compiled?

if you put the class def inside a function and dis.dis it, you get:

 >>> def foo():
 ...     class C(object):
 ...         __metaclass__ = MC
 ...         def m(self): return 'method m'
 ...     return C

Above we have *compiled* both foo and the class definition in its body, but we
have executed only the foo *definition*. (Note no complaint here about MC undefined)

 >>> import dis
 >>> dis.dis(foo)
   2           0 LOAD_CONST               1 ('C')
               3 LOAD_GLOBAL              0 (object)
               6 BUILD_TUPLE              1
               9 LOAD_CONST               2 (<code object C at 008FDF20, file "<stdin>", line 2>)

              12 MAKE_FUNCTION            0
              15 CALL_FUNCTION            0
              18 BUILD_CLASS
              19 STORE_FAST               0 (C)

   5          22 LOAD_FAST                0 (C)
              25 RETURN_VALUE
              26 LOAD_CONST               0 (None)
              29 RETURN_VALUE

Just to show when the class definition finishes:

 >>> def MC(*args): print args; return type(*args)

Now call foo to make the class *definition* in the body of foo execute (BTW triggering MC):

 >>> Cfoo = foo()
 ('C', (<type 'object'>,), {'m': <function m at 0x00903370>, '__module__': '__main__', '__metacla
 ss__': <function MC at 0x008FD4F0>})

(the printed args tuple above wrapped, obviously)

What we got:
 >>> Cfoo
 <class '__main__.C'>
 >>> Cfoo.m
 <unbound method C.m>
 >>> Cfoo().m
 <bound method C.m of <__main__.C object at 0x00901FD0>>

Bengt Richter

More information about the Python-list mailing list