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---","\n",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__方法