[Python-3000] yes to class decorators

Steven Bethard steven.bethard at gmail.com
Fri Nov 17 18:39:54 CET 2006


On 11/16/06, Josiah Carlson <jcarlson at uci.edu> wrote:
> but here's some abuse that I couldn't help chuckling
> over. No need to even bother constructing a class, but don't forget that
> 'return locals()' at the end!  (not that I'm advocating its [ab]use,
> just something that made me smile)
>
>  - Josiah
>
> >>> def metaclass(*bases):
> ...     def class_factory(fcn):
> ...         return type(fcn.__name__, bases, fcn())
> ...     return class_factory
> ...
> >>> @metaclass(object)
> ... def newclass():
> ...     def foo(self, arg):
> ...         print arg
> ...     return locals()
> ...
> >>> newclass().foo('hello!')
> hello!
> >>>

Of course, this is almost exactly what the class statement does under
the covers.  It makes a function object for the body of the class
statement, inserting a ``return locals()`` at the end.  When the class
statement is executed, that function is called::

>>> code = compile('class C(object): x = 1', '<string>', 'exec')
>>> dis.dis(code)
  1           0 LOAD_CONST               0 ('C')
              3 LOAD_NAME                0 (object)
              6 BUILD_TUPLE              1
              9 LOAD_CONST               1 (<code object C at
012EFF08, file "<string>", line 1>)
             12 MAKE_FUNCTION            0
             15 CALL_FUNCTION            0
             18 BUILD_CLASS
             19 STORE_NAME               1 (C)
             22 LOAD_CONST               2 (None)
             25 RETURN_VALUE
>>> dis.dis(code.co_consts[1])
  1           0 LOAD_NAME                0 (__name__)
              3 STORE_NAME               1 (__module__)
              6 LOAD_CONST               0 (1)
              9 STORE_NAME               2 (x)
             12 LOAD_LOCALS
             13 RETURN_VALUE

The important points in the code above are the ``MAKE_FUNCTION`` and
``CALL_FUNCTION`` from the class statement itself, and the
``LOAD_LOCALS`` and ``RETURN VALUE`` that were inserted at the end of
the code for the class's body.

STeVe
-- 
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy


More information about the Python-3000 mailing list