84 lines
2.3 KiB
Python
84 lines
2.3 KiB
Python
#!/usr/bin/env python
|
|
|
|
class Meta(type):
|
|
|
|
def __prepare__(class_name, bases):
|
|
"""
|
|
"Prepare" the new class. Here you can update the base classes.
|
|
|
|
:param name: Name of new class as a string
|
|
:param bases: Tuple of base classes
|
|
:return: Dictionary that initializes the namespace for the new class (must be a dict)
|
|
"""
|
|
print("in metaclass (class={}) __prepare__()".format(class_name), end=' ==> ')
|
|
print("params: name={}, bases={}".format(class_name, bases))
|
|
return {'animal': 'wombat', 'id': 100}
|
|
|
|
def __new__(metatype, name, bases, attrs):
|
|
"""
|
|
Create the new class. Called after __prepare__(). Note this is only called when classes
|
|
|
|
:param metatype: The metaclass itself
|
|
:param name: The name of the class being created
|
|
:param bases: bases of class being created (may be empty)
|
|
:param attrs: Initial attributes of the class being created
|
|
:return:
|
|
"""
|
|
print("in metaclass (class={}) __new__()".format(name), end=' ==> ')
|
|
print("params: type={} name={} bases={} attrs={}".format(metatype, name, bases, attrs))
|
|
return super().__new__(metatype, name, bases, attrs)
|
|
|
|
def __init__(cls, *args):
|
|
"""
|
|
|
|
:param cls: The class being created (compare with 'self' in normal class)
|
|
:param args: Any arguments to the class
|
|
"""
|
|
print("in metaclass (class={}) __init__()".format(cls.__name__), end=' ==> ')
|
|
print("params: cls={}, args={}".format(cls, args))
|
|
|
|
super().__init__(cls)
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
"""
|
|
Function called when the metaclass is called, as in NewClass = Meta(...)
|
|
|
|
:param args:
|
|
:param args:
|
|
:param kwargs:
|
|
:return:
|
|
"""
|
|
print("in metaclass (class={})__call__()".format(self.__name__))
|
|
|
|
|
|
class MyBase():
|
|
pass
|
|
|
|
print('=' * 60)
|
|
|
|
class A(MyBase, metaclass=Meta):
|
|
id = 5
|
|
|
|
def __init__(self):
|
|
print("In class A __init__()")
|
|
|
|
print('=' * 60)
|
|
|
|
class B(MyBase, metaclass=Meta):
|
|
animal = 'wombat'
|
|
|
|
def __init__(self):
|
|
print("In class B __init__()")
|
|
|
|
|
|
print('-' * 60)
|
|
m1 = A()
|
|
print('-' * 60)
|
|
m2 = B()
|
|
print('-' * 60)
|
|
m3 = A()
|
|
print('-' * 60)
|
|
m4 = B()
|
|
print('-' * 60)
|
|
print("animal: {} id: {}".format(A.animal, B.id))
|