Python-元类

Python-元类,第1张

Python-元类
  • 元类的含义
    • type创建类
  • 元类的理解
    • 普通创建类及对象执行过程
    • 元类创建类及对象执行过程
  • 元类的举例

元类的含义
  • 对象是由类实例化出来的。它的模板是类。那么类是怎么来的呢?它的模板是什么?
  • 元类是类的类,是类的模板。元类的实例为类,正如类的实例为对象。
  • 元类是用来控制如何创建类的,正如类是创建对象的模板一样。
  • type 是python 的一个内建元类,用来直接控制生成类,python中默认的任何class定义的类其实是 type 类实例化的对象。
  • 只有继承了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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/884282.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存