zoukankan      html  css  js  c++  java
  • 面向对象高级 之 元类

    元类:

      产生类的类(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'>  返回值是一个类,即要我们要的类

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

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

  • 相关阅读:
    初谈DHCP中继原理和配置
    css3渐变之linear-gradient与-webkit-linear-gradient写法异同
    mac svn 更新到新版本1.8
    mac显示所有文件、不产生.DS_Store文件
    mac自定义安装nodejs步骤
    nodejs 80端口监听失败及NODE_PATH不起作用的问题
    一种javascript链式多重继承的方式(__proto__原型链)
    apk反编译、smali修改、回编译笔记
    启用“关闭自动根证书更新”,解决Windows系统各种卡顿的问题(Visual studio 卡、远程桌面mstsc卡、SVN卡)
    SQL查询中关于索引使用的笔记
  • 原文地址:https://www.cnblogs.com/Afrafre/p/10146062.html
Copyright © 2011-2022 走看看