元类的使用

导读:

在Python里一切都是对象(object),基本数据类型,如数字,字符串,函数都是对象。对象可以由类(class)进行创建。那么既然一切都是对象,那么类是对象吗?

是的,类也是对象,那么又是谁创造了类呢?答案也很简单,也是类,一个能创作类的类,称之为元类(type)

1. 类的定义

对象是通过类创建的,如下面的代码:

# object 为顶层基类
class Work(object):
    a = 100

Mywork = Work()   # 实例化
print(Mywork )   # Mywork 是 Work 所创建的一个对象  <__main__.Work object at 0x101eb4630>
print(type(Mywork))    # <class '__main__.Work'>
print(type(Work))    # 类型为元类 <class 'type'>

解析:

  • 可以看见对象 Mywork 是类 Work 创建的实例。然但是可以看到Work的类型时由一个叫 type 的类创建的实例。即 Mywork —》 Work —》 type 创建

  • 上面的例子中对象是动态创建的,类则是通过关键字 class 声明定义的

  • 那么class关键字背后的玄机是什么呢?

    • 实际上,class Work(object) 这样的代码,等价于 Work = type(‘Work’, (objects, ), {“a”:100})
    • 即类 type 通过实例化创建了它的对象 Work,而这个 Work 恰恰是一个类,这样能创建类的类,就是 Python 的元类。而在python中内置的元类叫:type

一、什么是元类

  • 用来创建类的类,叫做元类
  • 类是元类创建出来的对象
  • 函数type实际上是一个元类,type就是Python在背后用来创建所有类的元类

二、注意区分元类和继承的基类

  • type是元类,所有的类都是通过type所创建出来的
  • object顶层的基类,所有类的继承顶层父类都是object

三、type 元类的使用

  1. 可以看到type是小写,一般情况下都会认为它是一个函数,通过查看源代码去看下如下定义的:

    class type(object):
    """
    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type
    """
    	# 实例化
    	def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__
    	     """
    	     type(object_or_name, bases, dict)
    	     type(object) -> the object's type
    	     type(name, bases, dict) -> a new type
    	     # (copied from class doc)
    	     """
    	     pass
    	     
    	# 创建类    
    	@staticmethod     # known case of __new__
        def __new__(*args, **kwargs):   # real signature unknown
            """ 
            Create and return a new object.  See help(type) for accurate signature. 
            (创建并返回一个新对象)
            """
            pass
    
  2. type的用法一:获取数据时那种类型 : type(object) -> the object’s type

    a = 100
    b = "100"
    c = [11,22,33]
    
    print(type(a))    # ======》 <class 'int'>
    print(type(b))    # ======》 <class 'str'>
    print(type(c))    # ======》 <class 'list'>
    
  3. type的用法二:创建类:type(object_or_name, bases, dict)

    1.在查看源码的时候,可以看到在初始化时,init__方法接受三个参数,type 在实例化的过程,也会重新创建一个新的类,而创建类的代码来自__new 方法,它的参数与 __init__方法是一样的。

    2.当调用 type 进行实例化的时候,会先自动调用 new 方法,再调用__init__方法,最终会实例化一个对象,这个对象是一个类。

    1. 元类 type 的 init 方法有3个参数:
     1.name:类名(字符串类型)
     2.bases:继承的父类(元祖类型)
     3.dict:属性和方法组成的字典(字典类型)
    

    具体例子:

    # 通过 class 定义类
    class Myclass(object):
        a = 100
        b = 200
    
    
    # 通过type创建的类(动态创建类)
    Myclass1 = type("Myclass1",(object,),{"a":"100","b":"200"})
    
    print(Myclass)
    print(Myclass1)
    

    在这里插入图片描述

    如果需要定义实例方法和类属性怎么办呢?,将方法和属性以字典的形式传进去

    def work(self):
        print("这是实例方法——————work————————")
    
    # 定义类属性值
    def init_method(self, aa, bb, cc):
        self.aa = aa
        self.bb = bb
        self.cc = cc
    		
    # 通过type创建的类(动态创建类)
    Myclass2 = type("Myclass2",(object,),{"a":"100","b":"200","work":work,"work_1":work_1,"__init__":init_method})
    
    m = Myclass2(11,22,33)
    m.work()
    print(m.aa, m.bb, m.cc)
    

    在这里插入图片描述

四、自定义元类的使用

  1. 既然元类可以创建类,那也可以自定义元类,自定义直接继承类 type ,在自定义元类的步骤:

    1.定义一个类继承type
    2.重写new方法

    具体例子:

    # 定义一个类继承type
    class Mytest(type):
    
    	# 重写new方法
        def __new__(cls, type_name, bases, atter, *args, **kwargs):
            new_cls = super().__new__(cls,type_name, bases, atter)         
            return new_cls      # 返回新的类
    
    M2 = Mytest("M2",(Mytest,),{"atter":100})
    print(M2)     # =====》  <class '__main__.M2'>
    
  2. 使用class创建类的时候指定自定义的元类

    1.不去指定时,默认创建都是type类
    2.指定自定义的元类去创建类:metaclass = 指定的元类

    class Myclass(type):
        """自定义的元类"""
    
        def __new__(cls, type_name, bases, attrs, *args, **kwargs):
            new_cls = super().__new__(cls, type_name, bases, attrs)
            print("这个是Myclass:", type_name, bases, attrs, )
            return new_cls
    
    # 通过metaclass=xxxx   继承自定义元类
    class Inherited_class(metaclass=Myclass):
        a = 100
        b = 200
    
    
    print(type(Inherited_class))  # ======》 <class '__main__.Myclass'>
    

    在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值