Skip to content


I learned some neat stuff at clepy last night

Brian Beck showed how to use metaclasses and descriptors to make DSLs with python.

I do this kind of this kind of thing every so often in my code:


def f(x):
    class C(object):
        y = x
    return C

That function takes a parameter and makes and returns a class based on that parameter. Whoop-di-do. I was surprised to learn that you can’t do this:


class C(object):
    x = 99
    class D(object):
        y = x + 1

I gotta explore this some more until it makes sense.

Here’s another neat trick: It isn’t possible to add two classes together:


>>> class C(object):
...     pass
...
>>> C + C
------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'type' and 'type'

But if you want to support this, the solution would be to define an __add__ method on the metaclass:


>>> type(C)
<type 'type'>
>>> class MC(type):
...     def __add__(self, other):
...         print 'Adding!'
...         return 99
... 
>>> class C(object):
...     __metaclass__ = MC
... 
>>> C + C
Adding!
99

Wacky, right? More realistically, I could build a new class by taking attributes of both classes together. In other words, if class C has a class attribute x, and class D has a class attribute y, then we can use a metaclass to add C and D together to get a new class E, that has both x and y as class attributes.

In this example, C has a class attribute x and D has a class attribute y. When I add the two classes, I get a new class with both of those class attributes.


>>> C.x, D.y
(99, 98)
>>> E = C + D
>>> E.x, E.y
(99, 98)

Here’s the metaclass that allows this sort of nonsense:


class MC(type):

    def __add__(self, other):

        class E(self):
            pass

        for k,v in other.__dict__.items():
            if k not in ('__dict__', ):
                setattr(E, k, v)

        return E

Posted in Cleveland Life, Programming, Python, clepy.

Viewing 1 Comment

 
close Reblog this comment
blog comments powered by Disqus