- 元类的含义
- type创建类
- 元类的理解
- 普通创建类及对象执行过程
- 元类创建类及对象执行过程
- 元类的举例
- 对象是由类实例化出来的。它的模板是类。那么类是怎么来的呢?它的模板是什么?
- 元类是类的类,是类的模板。元类的实例为类,正如类的实例为对象。
- 元类是用来控制如何创建类的,正如类是创建对象的模板一样。
- type 是python 的一个内建元类,用来直接控制生成类,python中默认的任何class定义的类其实是 type 类实例化的对象。
- 只有继承了type类才能称之为一个元类,否则就是一个普通的自定义类,自定义元类可以控制类的产生过程,类的产生过程其实就是元类。
-通常创建类和对象的方法
# 创建类
class Person():
def __init__(self):
print("-------Person init-------")
# 根据Person类创建对象p1
p1 = Person()
-使用type创建类
type(object_or_name, bases, dict)
参数1:class的名称,可以使用type查看。
参数2:继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法(tuple单元素写法(obj,));
参数3:class的属性和方法组合成字典形式。
Person1 = type("hello", (object,), dict(name="Jack", test=lambda self:print("-------Person test-------")))
print(type(Person1))
p1 = Person1()
print(type(p1))
print(p1.name)
p1.test()
result:
<class 'type'>
<class '__main__.hello'>
Jack
-------Person test-------
元类的理解
- 当创建类(定义类)的时候,相当是用元类(自定义的创建类的模板)或者默认的type元类生成了一个对象。
- metaclass=MyType指明创建类的元类,即模板。
# 当在定义一个对象时,会执行其模板类中的__new__,__init__方法。
class Person:
def __init__(self):
print("---------init---------")
def __new__(cls, *args, **kwargs):
print("---------new---------")
return super().__new__(cls, *args, **kwargs)
def __call__(self):
print("---------call---------")
p1 = Person() # 创建对象p1,会调用方法__new__, __init__
print("------------1----------")
p1() # 对象(), 会调用__call__
result:
---------new---------
---------init---------
------------1----------
---------call---------
元类创建类及对象执行过程
# Person指明metaclass=MyType, 则Person不由默认的type模板创建,而由MyType。
# 与之前类对象的实例化类似,创建对象会调用模板中定义的__new__,__init__方法。
class MyType(type):
def __init__(self, *args, **kwargs):
print("---------init---------")
super(MyType, self).__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
print("---------new---------")
return super().__new__(cls, *args, **kwargs)
class Person(metaclass=MyType):
def __call__(self):
print("--------Person call--------")
result:
---------new---------
---------init---------
class MyType(type):
def __init__(self, *args, **kwargs):
print("---------MyType init---------")
super(MyType, self).__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
print("---------MyType new---------")
return super().__new__(cls, *args, **kwargs)
def __call__(self, *args, **kwargs):
print("---------MyType call---------")
# 调用自己那个类的__new__的方法创建对象,生成地址
obj = self.__new__(self)
self.__init__(obj, *args, **kwargs)
return obj
class Person(metaclass=MyType):
def __init__(self):
print("-------Person init---------")
def __call__(self):
print("--------Person call--------")
print("------------1----------")
p1 = Person() # Person(), 相当于是MyType的对象Person的调用,会调用MyType的__call__方法。
print("------------2----------")
p1() # 调用Person中的call方法。
result:
---------MyType new---------
---------MyType init---------
------------1----------
---------MyType call---------
-------Person init---------
------------2----------
--------Person call--------
元类的举例
- 元类实现单例
class Singleton(type):
def __init__(self, name, bases, dict):
super(Singleton,self).__init__(name,bases, dict)
self._instance = None
def __call__(self, *args, **kwargs):
print("-----Singleton call-----")
if self._instance is None:
self._instance = super(Singleton,self).__call__(*args, **kwargs)
return self._instance
class MyClass(object,metaclass=Singleton):
a = 1
one = MyClass()
two = MyClass()
print(id(one))
print(id(two))
result:
-----Singleton call-----
-----Singleton call-----
2488406843688
2488406843688
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)