Created
May 28, 2011 19:54
-
-
Save gennad/997161 to your computer and use it in GitHub Desktop.
Metaclasses in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def make_hook(f): | |
"""Decorator to turn 'foo' method into '__foo__'""" | |
f.is_hook = 1 | |
return f | |
class MyType(type): | |
def __new__(cls, name, bases, attrs): | |
if name.startswith('None'): | |
return None | |
# Go over attributes and see if they should be renamed. | |
newattrs = {} | |
for attrname, attrvalue in attrs.iteritems(): | |
if getattr(attrvalue, 'is_hook', 0): | |
newattrs['__%s__' % attrname] = attrvalue | |
else: | |
newattrs[attrname] = attrvalue | |
return super(MyType, cls).__new__(cls, name, bases, newattrs) | |
def __init__(self, name, bases, attrs): | |
super(MyType, self).__init__(name, bases, attrs) | |
# classregistry.register(self, self.interfaces) | |
print "Would register class %s now." % self | |
def __add__(self, other): | |
class AutoClass(self, other): | |
pass | |
return AutoClass | |
# Alternatively, to autogenerate the classname as well as the class: | |
# return type(self.__name__ + other.__name__, (self, other), {}) | |
def unregister(self): | |
# classregistry.unregister(self) | |
print "Would unregister class %s now." % self | |
class MyObject: | |
__metaclass__ = MyType | |
class NoneSample(MyObject): | |
pass | |
# Will print "NoneType None" | |
print type(NoneSample), repr(NoneSample) | |
class Example(MyObject): | |
def __init__(self, value): | |
self.value = value | |
@make_hook | |
def add(self, other): | |
return self.__class__(self.value + other.value) | |
# Will unregister the class | |
Example.unregister() | |
inst = Example(10) | |
# Will fail with an AttributeError | |
#inst.unregister() | |
print inst + inst | |
class Sibling(MyObject): | |
pass | |
ExampleSibling = Example + Sibling | |
# ExampleSibling is now a subclass of both Example and Sibling (with no | |
# content of its own) although it will believe it's called 'AutoClass' | |
print ExampleSibling | |
print ExampleSibling.__mro__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
i dont get it