前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python面试题之Python中type和object的关系

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

作者头像
Jetpropelledsnake21
发布2018-08-01 15:11:43
1K0
发布2018-08-01 15:11:43
举报
文章被收录于专栏:JetpropelledSnake

知乎上看到的提问:

代码语言:javascript
复制
两个是互为实例的关系,但不是互为子类的关系,只有type是object的子类,反之则不成立。
大牛说两者是蛋生鸡鸡生蛋的关系,但我还是不明白,有懂的麻烦解释一下,
希望不要给出外文的链接。python为什么设计出两个,去掉一个行不行?

下面是jeff kit的回答: 给别人讲解过很多次,但写成文字是第一次。试一试吧,自己主要也是看了这篇文章(Python Types and Objects)才懂的。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 an 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是所有类的父亲,大部份我们直接使用的数据类型都存在这个列的。 第三列,实例列,实例是对象关系链的末端,不能再被子类化和实例化。

到现在为止,Python类型的秘密已经说穿了,不一小心连元类也暴露了。哎。慢慢消化吧,信息量很大。

=============更新============= 更新更新。。回答一下题主在问题后面说的为什么要有两个,而不是一个。如果type和object只保留一个,那么一定是object。只有object 时,第一列将不复存在,只剩下二三列,第二列表示类型,第三列表示实例,这个和大部分静态语言的类型架构类似,如java 。这样的架构将让python 失去一种很重要的动态特性–动态创建类型。本来,类(第二列的同学)在Python里面是一个对象(typeobject),对象是可以在运行时动态修改的,所以我们能在你定义一个类之后去修改他的行为或属性!拿掉第一列后,第二列变成了纯类型,写成怎样的,运行时行为就怎样。在这一点上,并不比静态语言有优势。所以,以上! =============补充============= 补充一个知乎上另一个人对该问题的简要回答 作者:刘鑫 简单的说,很多运行时体系(不一定是针对某种语言)都提供在运行时获取类型信息的功能,那么获取出来的是什么东西呢?获取出来的是一个描述类型信息的对象。那么所有描述类型信息的对象,都是“类型”这个类型的实例。这个type类型不是类型本身,而是用于描述类型的对象实例,类型本身是一种抽象的信息,type类的实例对象是它具体的信息载体。既然type类型也是一种类型,那么它是公共根类型object的一个派生,也就是合情合理的设计了。反过来,object 类型并不依赖 type 类型,最多它的一些反射/自省逻辑需要调用type。

参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档