• 面向对象高级 之 元类


    元类:

      产生类的类(type 为元类)

      #People = type(...)

      class People:

      type----(实例化)---> People------(实例化)--->   p对象

      class 意义:一遇到class, 调type 实例化结果赋给People

    产生类的两种方法: 1. class 产生(即type实例化的结果)

              2. 用内置的元类type 来实例化得到类

    type 函数语法:  type(' 类名', '类的基类', '类的名称空间')

    用type 实现 class People:  

    class_name = 'People'
    
    class_bases = (object,)  # 元组类型
    
    class_body = '''
    a = 1
    b = 2
    '''
    class_dic = {}
    exec = (class_body,{},class_dic)
    
    People = type(class_name,class_bases,class_dic) # 结果相当于class People

    type元类作用: 可以产生类,用来控制类的行为

    自定义元类目的: 1.通过__call__来控制类实例化对象的过程

             2.控制类的创建过程

    # 控制对象的实例化方法
    # 对象实例化,自动触发 __init__方法
    # 调用对象Person(),实际执行的是元类MyMeta 中的call方法
    
    # 1.自定义一个元类,元类也是一个类,但需要继承type
    class MyMeta(type):
        #self 表示Person,另外两个参数是调用类时传入的参数
        def __call__(self, *args, **kwargs):
            print('MyMeta 中的call run ')
            print(self,*args,**kwargs)
            # 得到一个对象的三个步骤
            #1,创建空对象
            obj = object.__new__(self)  # new一个Person类的空对象
            # 2.调用初始化方法
            self.__init__(obj,*args,**kwargs)
            # 3.得到一个完整的对象
            return obj
    
    
    # 2. 定义一个类
    class Person(metaclass=MyMeta):   # 将Person 的元类由默认的type改为MyMeta
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __call__(self, *args, **kwargs):
            print('call run....')
    
    # 调用Person 这个对象时,执行的是Person 的类(MyMeta)中的call 方法,return 了一个对象
    p = Person('egon',18)
    # 实例化对象的步骤(创建一个空对象,使用初始化方法,得到一个完整的对象
    print(p)  # 结果为Person 的对象,<__main__.Person object at 0x0000000001EADEB8>
    # 通过元类控制类的创建过程
    # 可以调用type 实例化产生一个类
    # 类由 类名,类的父类元组,类的名称空间 三个部分组成
    class_name = 'Myclass'
    base_classes = (object,)
    code = """
    name = "张三"
    age = 18
    def hello(self):
        print("hello %s" % self.name)
    """
    namespace = {}
    
    exec(code,{},namespace)
    
    res = type(class_name,base_classes,namespace)
    print(res)   #<class '__main__.Myclass'>  返回值是一个类,即要我们要的类

    单例模式:是一种设计模式或设计套路

      单个实例:一个类只有一个实例,称为单例(不管调多少次,拿到同一个对象)

  • 相关阅读:
    struts2校验器
    Struts2 验证框架 validation.xml 常用的验证规则
    MVC 无法找到资源
    架构设计
    金山西山居初赛第二场 美素数
    K Smallest Sums
    金山游戏编程复赛 连续最大积
    C++大作业之链表实现的高精度加法,减法,和数组实现的高精度乘法。
    POJ 3250 Bad Hair Day
    PoJ2492A Bug's Life并查集
  • 原文地址:https://www.cnblogs.com/Afrafre/p/10146062.html
Copyright © 2020-2023  润新知