object 和 type的关系很像鸡和蛋的关系,先有object还是先有type没法说,obejct和type是共生的关系,必须同时出现的。

在看下去之前,也要请先明白,在Python里面,所有的东西都是对象的概念。

在面向对象体系里面,存在两种关系:
- 父子关系,即继承关系,表现为子类继承于父类,如『蛇』类继承自『爬行动物』类,我们说『蛇是一种爬行动物』,英文说『snake is a kind of reptile』。在python里要查看一个类型的父类,使用它的__bases__属性可以查看。
- 类型实例关系,表现为某个类型的实例化,例如『萌萌是一条蛇』,英文说『萌萌 is an instance of snake』。在python里要查看一个实例的类型,使用它的__class__属性可以查看,或者使用type()函数查看。

这两种关系使用下面这张图简单示意,继承关系使用实线从子到父连接,类型实例关系使用虚线从实例到类型连接:

我们将使用一块白板来描述一下Python里面对象的关系,白板划分成三列:


先来看看type和object:
>>> object
<type 'object'>
>>> type
<type 'type'>
它们都是type的一个实例,表示它们都是类型对象。

在Python的世界中,object是父子关系的顶端,所有的数据类型的父类都是它;type是类型实例关系的顶端,所有对象都是它的实例的。它们两个的关系可以这样描述:
- object是一个type,object is and instance of type。即Object是type的一个实例。

>>> object.__class__
<type 'type'>
>>> object.__bases__ # object 无父类,因为它是链条顶端。
()
- type是一种object, type is kind of object。即Type是object的子类。

>>> type.__bases__
(<type 'object'>,)
>>> type.__class__ # type的类型是自己
<type 'type'>

此时,白板上对象的关系如下图:

我们再引入list, dict, tuple 这些内置数据类型来看看:
>>> list.__bases__
(<type 'object'>,)
>>> list.__class__
<type 'type'>
>>> dict.__bases__
(<type 'object'>,)
>>> dict.__class__
<type 'type'>
>>> tuple.__class__
<type 'type'>
>>> tuple.__bases__
(<type 'object'>,)
它们的父类都是object,类型都是type。

再实例化一个list看看:
>>> mylist = [1,2,3]
>>> mylist.__class__
<type 'list'>
>>> mylist.__bases__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__bases__'
实例化的list的类型是<type 'list'>, 而没有了父类。

把它们加到白板上去:

白板上的虚线表示源是目标的实例,实线表示源是目标的子类。即,左边的是右边的类型,而上面的是下面的父亲。
虚线是跨列产生关系,而实线只能在一列内产生关系。除了type和object两者外。

当我们自己去定个一个类及实例化它的时候,和上面的对象们又是什么关系呢?试一下:

>>> class C(object):
... pass
...
>>> C.__class__
<type 'type'>
>>> C.__bases__
(<type 'object'>,)

实例化
>>> c = C()
>>> c.__class__
<class '__main__.C'>
>>> c.__bases__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute '__bases__'
这个实例化的C类对象也是没有父类的属性的。
再更新一下白板:

白板上的第一列,目前只有type,我们先把这列的东西叫Type。
白板上的第二列,它们既是第三列的类型,又是第一列的实例,我们把这列的对象叫TypeObject。
白板上的第三列,它们是第二列类型的实例,而没有父类(__bases__)的,我们把它们叫Instance。

你以为事情就这样完了?不。。看见type孤零零在第一列其实不是那么舒服。。我们给它整几个玩伴看看。但要怎么整呢?要属于第一列的,必须是type的子类,那么我们只需要继承type来定义类就可以了:
>>> class M(type):
... pass
...
>>> M.__class__
<type 'type'>
>>> M.__bases__
(<type 'type'>,)
>>>
嗯嗯,M类的类型和父类都是type。这个时候,我们可以把它归到第一列去。那么,要怎么样实例化M类型呢?实例化后它应该出现在那个列?嗯嗯,好吧,刚才你一不小心创建了一个元类,MetaClass!即类的类。如果你要实例化一个元类,那还是得定义一个类:
>>> class TM(object):
... __metaclass__ = M # 这样来指定元类。
...
...
>>> TM.__class__
<class '__main__.M'> # 这个类不再是type类型,而是M类型的。
>>> TM.__bases__
(<type 'object'>,)

好了,现在TM这个类就是出现在第二列的。

再总结一下:
第一列,元类列,type是所有元类的父亲。我们可以通过继承type来创建元类。
第二列,TypeObject列,也称类列,object是所有类的父亲,大部份我们直接使用的数据类型都存在这个列的。
第三列,实例列,实例是对象关系链的末端,不能再被子类化和实例化。

为什么要有两个,而不是一个。

如果type和object只保留一个,那么一定是object。只有object 时,第一列将不复存在,只剩下二三列,第二列表示类型,第三列表示实例,这个和大部分静态语言的类型架构类似,如java 。
这样的架构将让python 失去一种很重要的动态特性--动态创建类型。本来,类(第二列的同学)在Python里面是一个对象(typeobject),对象是可以在运行时动态修改的,所以我们能在你定义一个类之后去修改他的行为或属性!拿掉第一列后,第二列变成了纯类型,写成怎样的,运行时行为就怎样。在这一点上,并不比静态语言有优势。
所以,以上!

 
转载
作者:jeff kit
链接:https://www.zhihu.com/question/38791962/answer/78172929
来源:知乎

python 中的object与type的关系的更多相关文章

  1. 【Python深入】Python中继承object和不继承object的区别

    python中定义class的时候,有object和没有object的不同?例如: class Solution(object): class Solution(): 这俩的区别在于—————— 在p ...

  2. Python 中的object takes no parameters错误

    Python是一门面向对象的语言,中我们首先创建一个类: class Student(object): def _init_(self,name,score): self.name = name se ...

  3. python中的object

    继承 object 类的是新式类,不继承 object 类的是经典类,在 Python 2.7 里面新式类和经典类在多继承方面会有差异: class A: def foo(self): print(' ...

  4. python中time类型,datetime类型的关系与互相转换

    一.time模块 time模块提供各种操作时间的函数       一般有两种表示时间的方式:       第一种是时间戳的方式(相对于1970.1.1 00:00:00以秒计算的偏移量),时间戳是惟一 ...

  5. python中赋值-浅拷贝-深拷贝之间的关系

    赋值: 变量的引用,没有拷贝空间 对象之间赋值本质上 是对象之间的引用传递而已.也就是多个对象指向同一个数据空间. 拷贝的对象分两种类型: . 拷贝可变类型 浅拷贝: 只拷贝第一层数据,不关心里面的第 ...

  6. python中元组与小括号的关系

    在学习Python 的时候.说到有两种数据类型,一种叫 列表,一种叫做元组,可以认为,元组是功能精简的列表.因为它少了列表很多功能.但是又有相识.定义他们的时候,主要是用中括号和小括号之分. 例如:定 ...

  7. Python面试题之Python中type和object的关系

    知乎上看到的提问: 两个是互为实例的关系,但不是互为子类的关系,只有type是object的子类,反之则不成立. 大牛说两者是蛋生鸡鸡生蛋的关系,但我还是不明白,有懂的麻烦解释一下, 希望不要给出外文 ...

  8. Python中type与Object的区别

    Python中type与Object的区别 在查看了Python的API后,总算明白了.现在总结如下: 先来看object的说明: Python中关于object的说明很少,甚至只有一句话: clas ...

  9. [py]python中的特殊类class type和类的两面性图解

    生活中的模具 生活中 编程 万物都从无到有, 起于烟尘 () 生产原料,铁 object 车床-生产各类模具 元类即metaclass,对应python的class type 模具-生产各类实在的物品 ...

随机推荐

  1. redis5.0主从配置

    1.下载 wget http://download.redis.io/releases/redis-5.0.3.tar.gz .tar.gz cd redis- make make test //检查 ...

  2. (转)Elasticsearch分析聚合

    Elasticsearch不仅仅适合做全文检索,分析聚合功能也很好用.下面通过实例来学习. 一.准备数据 {"index":{ "_index": " ...

  3. LeetCode-MinimumDepthOfBinaryTree

    题目: Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the ...

  4. Lower Power with CPF(四)

    CPF从Front-end到Back-end(RTL--GDSII)的整个流程: 1)Creating a CPF file:来在前端就建立lower power的规范. 2)检查CPF文件的正确性, ...

  5. sql when null 判断

    Sql Server 中使用case when then 判断某字段是否为null,和判断是否为字符或数字时的写法不一样,如果不注意,很容易搞错 错误方法: CASE columnName WHEN ...

  6. 大杀器Bodymovin和Lottie:把AE动画转换成HTML5/Android/iOS原生动画

    前段时间听部门老大说,Airbnb出了个移动端的动画库Lottie,可以和一个名叫Bodymovin的AE插件结合起来,把在AE上做好的动画导出为json文件,然后以Android/iOS原生动画的形 ...

  7. python 文件操作,os.path.walk()的回调函数打印文件名

    #coding=utf-8 import osdef find_file(arg,dirname,files):    #for i in arg:        #print i for file ...

  8. 2016NOI冬令营day3

    上午第一课堂  第一次感觉能听... IOI题目选讲挺不错的,比较有趣(yong4) :) 然而接下来的“基础”数据结构就太神了,完全不会QAQ :( 下午我听得比较认真,VFK讲的是下一代评测系统 ...

  9. 9大行为导致Java程序员薪资过低, 你有几个?

    Java程序员薪水有高有低,有的人一个月可能拿30K.50K,有的人可能只有2K.3K.同样有五年工作经验的Java程序员,可能一个人每月拿20K,一个拿5K.是什么因素导致了这种差异?本文整理导致J ...

  10. Python Web学习笔记之CPU时间片

    时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的.如果在时 间片结束时进程还在运行,则CPU将被剥夺并分配给另一个 ...