python面向对象——元类metaclass

python3,所有的类型都是新式类,对象有类创建,类则是有元类创建
未指定就是默认使用type

创建一个类,就是使用type()进行实例化

利用type创建一个类 名称为Pople

type(类名,元组,字典)
类名:必须是字符串类型
元组:表示继承关系
字典:属性

"方法一"
# class Foo:
#     def func(self):
#         print("from func")


"方法二"

# def func(self):
#     print("from func")
# a = type("People",(),{"name":"kyle","func":func})
# print(a.__dict__)
# print(a.__str__)
# print(a.name)

"一个类没有声明自己的元类,默认的是type。因此可以通过继承type自定义元类"
# class Mymetan(type):
#
#     def __init__(self,class_name,bases=None,dict=None):
#         print("from my mytype init----")
#         print(self)
#         print(class_name)
#         print(bases)
#         print(dict)
#
#     def __call__(self, *args, **kwargs):
#         print("mytype call---","
",self,args,kwargs)
#         obj = self.__new__(self)
#         self.__init__(obj,*args,**kwargs)
#         return obj
#
# class People(metaclass=Mymetan):
#     #__metaclass__=MyType python2
#
#     def __init__(self,name):
#         print("People--->>")
#         self.name=name

# p1 = People("kyle")
# print(p1.__dict__)


"""创建对象的流程步骤"""
# class Mytype(type):
#     def __init__(self,name,bases=None,dict=None):
#         print("mytype init")
#
#     def __call__(self, *args, **kwargs):
#         print("1-----step")
#         obj = self.__new__(self)
#         print("3----step")
#         self.__init__(obj,*args,**kwargs)
#         print("5-----step")
#         return obj
#
# class Foo(object,metaclass=Mytype):
#     x = 1
#
#     def __init__(self,name):
#         print("4---step")
#         self.name = name
#
#
#     def __new__(cls, *args, **kwargs):
#         print("2---step")
#         return super().__new__(cls)
#
# f1 = Foo("kyle")
# print(f1.__dict__)

"""元类"""

# class Mytype(type):
#     def __init__(self,name,bases=None,dict=None):
#         print("mytype init")
#
#     def __new__(cls, *args, **kwargs):
#         print("----新建class就会触发")
#         return type.__new__(cls, *args, **kwargs)
#
#     def __call__(self, *args, **kwargs):
#         print("1-----step--Mytype.call")
#         obj = self.__new__(self)
#         print("3----step")
#         self.__init__(obj,*args,**kwargs)
#         print("5-----step")
#         return obj
#
# class Foo(object,metaclass=Mytype):
#     x = 1
#
#     def __init__(self,name):
#         print("4---step---Foo.init")
#         self.name = name
#
#
#     def __new__(cls, *args, **kwargs):
#         print("2---step--Foo.new")
#         return super().__new__(cls)
#
#
# f = Foo("kyle")

python 一切都是对象,因此类也是对象
名字加括号(如:Foo()),这本质就是调用父类的__call__方法(即:type.call):
父类的__call__方法执行两部分:
调用自己的__new__方法,(即Foo类的定义的__new__)
调用自己的__init__方法,(即Foo.init

总结:元类的难点在于执行顺序很绕,其实我们只需要记住两点就可以了
1、谁后面跟括号,就从谁的爹中找__call__方法执行
type->Mymeta->Foo->obj
Mymeta()触发type.call
Foo()触发Mymeta.call
obj()触发Foo.call
2、__call__内按先后顺序依次调用儿子的__new__和__init__方法

原文地址:https://www.cnblogs.com/greatkyle/p/6797020.html