Some examples of metaclasses definitions
class MetaClass(type):
def get_foo(self):
return self._foo
def set_foo(self, value):
self._foo = value
foo = property(get_foo)
@property
def bar(self):
return self._bar
class MyClass(object, metaclass=MetaClass):
# not defining raises an AttributeError
# _foo = 'abc'
# _bar = 'def'
@classmethod
def print_meta(cls):
print(cls.foo)
print(cls.bar)
someclass = MyClass()
someclass.print_meta()
# hello_metaclass.py
# A simple metaclass
# This metaclass adds a 'hello' method to classes that use the metaclass
# meaning, those classes get a 'hello' method with no extra effort
# the metaclass takes care of the code generation for us
class HelloMeta(type):
# A hello method
@property
def _bye(self):
raise NotImplementedError('duh')
def _hello(cls):
print("greetings from %s, a HelloMeta type class" % (type(cls())))
# Call the metaclass
def __call__(self, *args, **kwargs):
# create the new class as normal
cls = type.__call__(self, *args)
setattr(cls, "bye", self._bye)
# define a new hello method for each of these classes
setattr(cls, "hello", self._hello)
# return the class
return cls
# Try out the metaclass
class TryHello(object, metaclass=HelloMeta):
HelloMeta._bye = 'abc'
def greet(self):
print(self.bye)
self.hello()
# Create an instance of the metaclass. It should automatically have a hello method
# even though one is not defined manually in the class
# in other words, it is added for us by the metaclass
greeter = TryHello()
greeter.greet()
import abc
class HelloMeta(abc.ABC):
# A hello method
@property
@abc.abstractmethod
def bye(self):
raise NotImplementedError
@classmethod
def hello(cls):
print("greetings from %s, a HelloMeta type class" % (type(cls())))
# Call the metaclass
def __call__(self, *args, **kwargs):
# create the new class as normal
cls = type.__call__(self, *args)
# define a new hello method for each of these classes
setattr(cls, "hello", self.hello)
# return the class
return cls
class Hello(HelloMeta):
bye = "I'm an abstract property" # if not defined, raises a TypeError
def greet(self):
self.hello()
greeter = Hello()
greeter.hello()
greeter.greet()
print(greeter.bye)