美文网首页Python全栈
29.Python之面向对象的元类

29.Python之面向对象的元类

作者: 免跪姓黄 | 来源:发表于2020-03-14 18:48 被阅读0次

    Python之面向对象的元类

    1. 什么是元类?

      • 类的类就是元类,元类创建对象。使用class定义的类,用来产生程序员自己的对象;而class定义的类,是由内置的元类type产生的。

        class Chinese:  # 默认的元类是type
            country = 'China'
        
            def __init__(self, name, age, sex):
                self.name = name
                self.age = age
                self.sex = sex
        
      • 使用class定义类等同于使用以下方式定义类:

        class_name = 'Chinese'
        class_base = (object,)    # 基类为元组
        class_body = '''
        country = 'China'
        def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        elf.sex = sex
        '''
        class_dic = {}
        exec(class_body, {}, class_dic)    # 产生类的名称空间
        
        # 类的三大要素,类名,基类,类的名称空间
        Chinese = type(class_name, class_base, class_dic)
        

    1. 为什么要有元类?

      • 控制类的创建和行为。

    1. 怎么样自定义元类?

      class MyMetaclass(type):  # 继承type并且可以派生
          def __init__(self, class_name, class_base, class_dic):  # self=Foo
              if not class_name.istitle():  # 可以控制创建类时名字的命名规范
                  raise TypeError('类的名字必须首字母大写')
              if not class_dic.get('__doc__'):
                  raise TabError('创建类必须写好描述信息')
              super(MyMetaclass, self).__init__(class_name, class_base, class_dic)
      
          def __call__(self, *args, **kwargs):
              # 当执行 Foo(1) 时会做以下事情:
              # 1.创造一个空对象obj
              obj = object.__new__(self)
              # 2.调用 Foo.__init__,并将obj连同Foo括号内的参数一同传给Foo.__init__(self.y)
              self.__init__(obj, *args, **kwargs)
              return obj
      
          pass
      
      
      class Foo(object,metaclass = MyMetaclass):  # 由于Python中一切皆对象,因此Foo是元类type实例化而来,默认实例化通过Foo=type('Foo',(object,),class_dic)完成,现在是Foo=MyMetaclass('Foo',(object,),class_dic)完成实例化
          '''
          描述信息
          '''
          x = 1
          
          def __init__(self, y):
              self.y = y
      
          def f(self):
              print('from f')
      
      
      print(Foo.__doc__)  # 查看类的描述信息
      
      Foo(1)
      

    1. 单例模式

      • 单个实例,节省内存,单例模式用在对象内存的数据属性是一样的情况下,就没必要开辟新的内存空间了,因此要使用单例模式节省内存。

    相关文章

      网友评论

        本文标题:29.Python之面向对象的元类

        本文链接:https://www.haomeiwen.com/subject/rptnshtx.html