MyMeta.__prepare__
MyMeta.__new__
MyMeta.__init__
MyMeta.__prepare__
MyMeta.__new__MyClass.__init_subclass__ 在元类的new函数中隐藏调用了父类的init_subclass函数
MyMeta.__init__
MyMeta.__call__ 隐藏调用了子类的__new__和__init__MyDerivedClass.__new__
MyClass.__new__(子类明确调用了父类的new)
MyDerivedClass.__init__
MyClass.__init__(子类明确调用了父类的init)
import functools
__all__ = ("my_decorator", "MyMeta", "MyBase", "MyClass", "MyDerivedClass",
"main_run")
def __dir__():
return __all__
def my_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
args_str = ", ".join(map(str, args))
kwargs_str = ", ".join(map(lambda kv: "=".join(map(str, kv)),
kwargs.items()))
if args_str and kwargs_str:
all_str = ", ".join((args_str, kwargs_str))
else:
all_str = args_str + kwargs_str
func_call_prompt = f"{func.__qualname__}({all_str})"
print(f"{func_call_prompt}, Begin...")
result = func(*args, **kwargs)
print(f"{func_call_prompt}={result}, End!")
return result
return wrapper
class MyMeta(type):
""""""
@my_decorator
def __new__(mcs, what, bases=None, cls_dict=None, **kwargs):
"""mcs:指的是本元类"""
new_dict = {}
new_dict.update(cls_dict)
new_dict.update(kwargs)
return super().__new__(mcs, what, bases, new_dict)
@my_decorator
def __init__(cls, what, bases=None, cls_dict=None, **kwargs):
"""cls:指要生成的类,函数参数是这种样式,可以参见type.__init__定义"""
super().__init__(what, bases, cls_dict)
@my_decorator
def __call__(cls, *args, **kwargs):
"""cls:指要生成的类,*args, **kwargs是类的__init__函数参数"""
return super().__call__(*args, **kwargs)
@classmethod
@my_decorator
def __prepare__(mcs, name, bases, **kwargs):
print(mcs, name, bases, kwargs)
return super().__prepare__(name, bases, **kwargs)
class MyBase:
pass
class MyClass(MyBase, metaclass=MyMeta, class_id=1234):
name = ""
@my_decorator
def __new__(cls, *args, **kwargs):
"""mcs:指的是本元类"""
return super().__new__(cls)
@my_decorator
def __init__(self, name="", age=0):
self.age = age
self.name = name
@my_decorator
def __call__(self, *args, **kwargs):
print("MyClass.__call__ working")
@my_decorator
def __init_subclass__(cls, **kwargs):
print(cls, kwargs)
class MyDerivedClass(MyClass, tag="div"):
tag = ""
@my_decorator
def __new__(cls, *args, **kwargs):
"""mcs:指的是本元类"""
return super().__new__(cls)
@my_decorator
def __init__(self, name="", age=0, height=0):
super().__init__(name, age)
self.height = height
@my_decorator
def __call__(self, *args, **kwargs):
super().__call__(*args, **kwargs)
print("MyDerivedClass.__call__ working")
@my_decorator
def hello(*args, **kwargs):
print(args, kwargs)
def main_run():
"""主函数"""
my = MyDerivedClass("Tom", age=56)
print(my.class_id, my.tag)
my()
if __name__ == "__main__":
main_run()
结果输出:
MyMeta.__prepare__(, MyClass, (,), class_id=1234), Begin...
MyClass (,) {'class_id': 1234}
MyMeta.__prepare__(, MyClass, (,), class_id=1234)={}, End!
MyMeta.__new__(, MyClass, (,), {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': ...}, class_id=1234), Begin...
MyMeta.__new__(, MyClass, (,), {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': ...}, class_id=1234)=, End!
MyMeta.__init__(, MyClass, (,), {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': ...}, class_id=1234), Begin...
MyMeta.__init__(, MyClass, (,), {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': ...}, class_id=1234)=None, End!
MyMeta.__prepare__(, MyDerivedClass, (,), tag=div), Begin...
MyDerivedClass (,) {'tag': 'div'}
MyMeta.__prepare__(, MyDerivedClass, (,), tag=div)={}, End!
MyMeta.__new__(, MyDerivedClass, (,), {'__module__': '__main__', '__qualname__': 'MyDerivedClass', 'tag': '', '__new__': ...}, tag=div), Begin...
MyClass.__init_subclass__(), Begin...
{}
MyClass.__init_subclass__()=None, End!
MyMeta.__new__(, MyDerivedClass, (,), {'__module__': '__main__', '__qualname__': 'MyDerivedClass', 'tag': '', '__new__': ...}, tag=div)=, End!
MyMeta.__init__(, MyDerivedClass, (,), {'__module__': '__main__', '__qualname__': 'MyDerivedClass', 'tag': '', '__new__': ...}, tag=div), Begin...
MyMeta.__init__(, MyDerivedClass, (,), {'__module__': '__main__', '__qualname__': 'MyDerivedClass', 'tag': '', '__new__': ...}, tag=div)=None, End!
MyMeta.__call__(, Tom, age=56), Begin...
MyDerivedClass.__new__(, Tom, age=56), Begin...
MyClass.__new__(), Begin...
MyClass.__new__()=<__main__.MyDerivedClass object ...>, End!
MyDerivedClass.__new__(, Tom, age=56)=<__main__.MyDerivedClass object at ...>, End!
MyDerivedClass.__init__(<__main__.MyDerivedClass object at ...>, Tom, age=56), Begin...
MyClass.__init__(<__main__.MyDerivedClass object at ...>, Tom, 56), Begin...
MyClass.__init__(<__main__.MyDerivedClass object at ...>, Tom, 56)=None, End!
MyDerivedClass.__init__(<__main__.MyDerivedClass object at ....>, Tom, age=56)=None, End!
MyMeta.__call__(, Tom, age=56)=<__main__.MyDerivedClass object at ...>, End!
1234 div
MyDerivedClass.__call__(<__main__.MyDerivedClass object at ...>), Begin...
MyClass.__call__(<__main__.MyDerivedClass object at ...>), Begin...
MyClass.__call__ working
MyClass.__call__(<__main__.MyDerivedClass object at ...>)=None, End!
MyDerivedClass.__call__ working
MyDerivedClass.__call__(<__main__.MyDerivedClass object at ...>)=None, End!
type(OtherClass)
都是type,表示类是type的实例此时,只存在类的创建,这时候类相当于元类(缺省时type)的实例,而实例的创建时调用对象的__new__和__init__
def main_run():
"""主函数"""
输出如下:
MyMeta.__new__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) Begin...
MyMeta.__new__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) End!
MyMeta.__init__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) Begin...
MyMeta.__init__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) End!
| | | |
创建类实例(将类,元类的实例作为可调用对象进行调用),相当于调用了元类的__call__,call__中调用了类的__new__和__init
def main_run():
"""主函数"""
my = MyClass("Tom", age=56)
输出如下:
MyMeta.__new__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) Begin...
MyMeta.__new__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) End!
MyMeta.__init__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) Begin...
MyMeta.__init__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) End!
MyMeta.__call__( ('Tom',) {'age': 56} ) Begin...
MyClass.__new__(: ('Tom',) {'age': 56} ) Begin...
MyClass.__new__(: ('Tom',) {'age': 56} ) End!
MyClass.__init__( <__main__.MyClass object at 0x0000026AD903F910> Tom 56 ) Begin...
MyClass.__init__( <__main__.MyClass object at 0x0000026AD903F910> Tom 56 ) End!
MyMeta.__call__( ('Tom',) {'age': 56} ) End!
| | | |
类实例作为可调用对象,进行调用
def main_run():
"""主函数"""
my = MyClass("Tom", age=56)
my()
输出如下:
MyMeta.__new__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) Begin...
MyMeta.__new__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) End!
MyMeta.__init__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) Begin...
MyMeta.__init__( MyClass (,) {'__module__': '__main__', '__qualname__': 'MyClass', 'name': '', '__new__': , '__init__': , '__call__': , '__classcell__': } ) End!
MyMeta.__call__( ('Tom',) {'age': 56} ) Begin...
MyClass.__new__(: ('Tom',) {'age': 56} ) Begin...
MyClass.__new__(: ('Tom',) {'age': 56} ) End!
MyClass.__init__( <__main__.MyClass object at 0x0000026AD903F910> Tom 56 ) Begin...
MyClass.__init__( <__main__.MyClass object at 0x0000026AD903F910> Tom 56 ) End!
MyMeta.__call__( ('Tom',) {'age': 56} ) End!
MyClass.__call__(: <__main__.MyClass object at 0x0000026AD903F910> () {} ) Begin...
MyClass.__call__ working
MyClass.__call__(: <__main__.MyClass object at 0x0000026AD903F910> () {} ) End!
| | | |