classMyMeta(type):"""
We define a meta class: a meta class is a class describing what a class is.
"""def__new__(mcs, name, bases, dct):"""
called when the class is created
:param mcs: the meta-class
:param name: the name of the class that is created
:param bases:
:param dct:
"""
print(f'mcs: {mcs}\n name: {name}\n bases: {bases} \n dct: {dct}')
return type.__new__(mcs, name, bases, dct)
def__init__(self, *args, **kwargs):
print(f'self: {self}\n args: {args}\n kwargs: {kwargs}')
return type.__init__(self, *args, **kwargs)
classMyClass(metaclass=MyMeta):pass# Instantiate the class#my_instance = MyClass()
classMetaClassWithDoc(type):"""
This meta-class is like type but it checks at the creation (in __new__ of the class)
that all methods have a docstring (__doc__ field is defined)
"""def__new__(cls, name, bases, dct):for attr, value in dct.items():
if callable(value) andnot value.__doc__:
raise TypeError(f'Method {attr} must have a docstring')
return super().__new__(cls, name, bases, dct)
classDocumentedClass(metaclass=MetaClassWithDoc):"""
All methods of this class should be documented. Otherwise, BOOM.
"""defmethod_with_docstring(self):"""This method is documented."""pass# def method_without_docstring(self):# pass # This will raise a TypeError
import types
from time import time
classTimerMetaClass(type):"""
meta-class for classes with methods that are timed
"""def__new__(mcs, name, bases, dct):defgetTimedVerionOfMethod(name, method):deftimedVersionFunctionOfMethod(self, *args, **kwargs):
t = time()
result = method(self, *args, **kwargs)
print("Appel de %s :\t%s" % (name, time() - t))
return result
timedVersionFunctionOfMethod.__name__ = method.__name__
timedVersionFunctionOfMethod.__doc__ = method.__doc__
timedVersionFunctionOfMethod.__dict__ = method.__dict__
return timedVersionFunctionOfMethod
d = {}
for name, slot in dct.items():
if type(slot) is types.FunctionType:
d[name] = getTimedVerionOfMethod(name, slot)
else:
d[name] = slot
return type.__new__(mcs, name, bases, d)
classA(metaclass=TimerMetaClass):defm(self):pass
a = A()
a.m()