Meta Classes

In [1]:
x = 1
In [2]:
type(x)
Out[2]:
int
In [3]:
type(int)
Out[3]:
type
In [4]:
type(type)
Out[4]:
type
In [6]:
int("2")
Out[6]:
2
In [7]:
Point = type("Point", (object,), {"x": 0, "y": 0})
In [8]:
Point
Out[8]:
__main__.Point
In [9]:
type(Point)
Out[9]:
type
In [10]:
Point2 = type("Point2", (), {})
In [11]:
type(Point2)
Out[11]:
type

Can we extend type?

In [12]:
class type2(type): pass
In [13]:
A = type2("A", (), {})
In [14]:
A
Out[14]:
__main__.A
In [15]:
type(A)
Out[15]:
__main__.type2
In [16]:
class B(object):
    __metaclass__ = type2
    
In [17]:
B
Out[17]:
__main__.B
In [18]:
type(B)
Out[18]:
__main__.type2
In [21]:
# Can a metaclass be a string?
def fakemeta(name, bases, attrs):
    return 1
class C(object):
    __metaclass__ = fakemeta
In [22]:
C
Out[22]:
1

Practical uses?

In [24]:
mapping = []

class metapage(type):
    def __init__(cls, name, bases, attrs):
        type.__init__(cls, name, bases, attrs)
        url = "/" + name
        mapping.append((url, cls))

class page:
    __metaclass__ = metapage

print mapping
class hello(page):
    def get(self):
        return "hello, world!"

print mapping
class bye(page):
    def get(self):
        return "goodbye!"
print mapping
[('/page', <class '__main__.page'>)]
[('/page', <class '__main__.page'>), ('/hello', <class '__main__.hello'>)]
[('/page', <class '__main__.page'>), ('/hello', <class '__main__.hello'>), ('/bye', <class '__main__.bye'>)]
In [25]:
# It is a common practice to base class construtor in the subclass
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
class Point3D(Point):
    def __init__(self, x, y, z):
        Point.__init__(self, x, y)
        self.z = z
        

Most common use of metaclass is:

class Post(db.Model):
    title = StringColumn()
    timestamp = DateColumn()
In [25]:
 
In [ ]: