Python中的类与类型示例详解


Posted in Python onJuly 10, 2019

1.经典类与新式类

在了解Python的类与类型前,需要对Python的经典类(classic classes)与新式类(new-style classes)有个简单的概念。

在Python 2.x及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性;反之,即不由任意内置类型派生出的类,则称之为“经典类”。

“新式类”和“经典类”的区分在Python 3.x之后就已经不存在,在Python 3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”。

官方文档https://www.python.org/doc/newstyle/

2.类的实例与对象

在很多语言中,类的实例与类的对象,只是同一事物的不同名称。而在Python中,类的对象与类的实例,是完全不同的概念。在本文中,所称的类对象,是指由class代码块执行后创建的类对象,而类的实例则是由类对象所创建的实例。这里只做简单提及,便于下文理解,要更深入的理解这个概念,可以参考“python一切皆对象”的相关知识。

3.类实例的类与类型

尝试分别在Python 2.x 和 3.x 版本中运行如下代码:

class A():pass
class B():pass

a = A()
b = B()

if __name__ == '__main__':
  print(type(a))
  print(type(b))
  print(type(a) == type(b))
  print(a.__class__)
  print(b.__class__)
  print(a.__class__ == b.__class__)

Python 2.6.9 及 2.7.10 的运行结果:

Python中的类与类型示例详解

在Python 2.x及以前的版本,所有经典类的实例都是“instance”(实例类型)。所以比较经典类实例的类型(type)毫无意义,因为所有的经典类实例都是instance类型,比较的结果通常为True。更多情况下需要比较经典类实例的__class__属性来获得我们想要的结果(或使用isinstance函数)。

Python 3.5.1 运行结果

Python中的类与类型示例详解

在Python 3.x及之后的版本,类和类型已经合并。类实例的类型是这个实例所创建自的类(通常是和类实例的__class__相同),而不再是Python 2.x版本中的“instance”实例类型。

需要注意的是,在Python 2.x版本中,“经典类的实例都是instance类型”,这个结论只适用于经典类。对新式类和内置类型的实例,它们的类型要更加明确。

修改之前的代码验证上述观点,尝试让class a 和 class b 显示继承自object,成为“新式类”。

class A(object):pass
class B(object):pass

a = A()
b = B()

if __name__ == '__main__':
  print(type(a))
  print(type(b))
  print(type(a) == type(b))
  print(a.__class__)
  print(b.__class__)
  print(a.__class__ == b.__class__)

Python 2.7.10 运行结果:

Python中的类与类型示例详解

代码运行结果和Python 3.x是完全相同的,可以看出Python 2.x 新式类实例的类型就是这个实例所创建自的类。同时进一步印证在Python 3.x中所有的类都是新式类(显示或隐式继承自object类)。

接着对内置类型进行验证,尝试运行以下代码

print(type([1, 2, 3]))

Python 2.7.10运行结果:

Python中的类与类型示例详解

可以看出,内置类型实例的类型,也是同新式类一样,是这个实例所创建自的类。在示例代码中,我们创建了一个list,所以实例的类型为list类型。

4.类的类型

如果说,一个类实例的类型是创建它的类(python 3.x),那一个类的类型又是什么???

继续使用代码尝试验证:

class A():pass
class B():pass

if __name__ == '__main__':
  print(type(A))
  print(type(B))
  print(type(A) == type(B))

Python 2.7.10 运行结果:

Python中的类与类型示例详解

从运行结果我们可以看出,在Python 2.x 中,经典类的类型都是classobj。type(A) == type(B)结果为True,说明它们是同一种类型。

Python 3.5.1运行结果:

Python中的类与类型示例详解

从运行结果我们可以看出,所有的类型都是type类,再次印证在Python 3.x 类与类型已经完全合并,类即类型,类型即类。

再次修改代码,使 class A 和 B 显式继承自 object,成为新式类,再在Python 2.7.10 下运行查看结果:

Python中的类与类型示例详解

运行结果显而易见,和Python 3.x 是一样的,因为它们都是新式类。

注:在运行结果中,Python 2.x 显示为 <type 'type'>,而 Python 3.x 显示为<class 'type'>, 仅是显示方法不同,可以理解为等价,因为在Python 3.x类即类型。

参考官方文档:https://docs.python.org/3/library/stdtypes.html#bltin-type-objects

Type objects represent the various object types. An object's type is accessed by the built-in functiontype(). There are no special operations on types. The standard moduletypesdefines names for all standard built-in types.

Types are written like this:<class'int'>.

再来进行一个有趣的尝试:

print(type(type))

在python 2.x 和 3.x 运行结果都是一样的,type类型本身也是类(新式类和内置类型的类与类型已经合并),它自己也是type类型。

Python中的类与类型示例详解

Python中的类与类型示例详解

5.类是Type类的实例

有上文的测试可以得知:所有的类型都是type类。从另一个角度理解,类就是type类的实例,所有的新式类,都是由type类实例化创建而来,并且显式或隐式继承自object。

type([1, 2, 3])

得到运行结果:<class 'list'>,说明[1, 2, 3]这个list是list类的实例。

同样的

type(list)

得到运行结果:<class 'type'>,也可以说明list这个类是type类的实例。

通过调用__class__属性可以得到同样的结果:

list.__class__
[1, 2, 3].__class__

说明类对象是type类的实例。

6.有趣的循环

前文提到,在Python 3.x 中,所有的类都显式或隐式的派生自object类,type类也不例外。类型自身派生自object类,而object类派生自type,二者组成了一个循环的关系。

通过以下代码来验证

isinstance(object, type)
isinstance(type, object)

运行结果:

Python中的类与类型示例详解

从运行结果可以看出object是type类型, type类型也是object类型

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python中__new__与__init__方法的区别详解
May 04 Python
实例讲解Python编程中@property装饰器的用法
Jun 20 Python
Python+Turtle动态绘制一棵树实例分享
Jan 16 Python
Python使用win32 COM实现Excel的写入与保存功能示例
May 03 Python
将Dataframe数据转化为ndarry数据的方法
Jun 28 Python
Python对象与引用的介绍
Jan 24 Python
一文秒懂python读写csv xml json文件各种骚操作
Jul 04 Python
python爬虫神器Pyppeteer入门及使用
Jul 13 Python
Python Subprocess模块原理及实例
Aug 26 Python
如何在 Django 模板中输出 &quot;{{&quot;
Jan 24 Python
Python发送手机动态验证码代码实例
Feb 28 Python
Numpy(Pandas)删除全为零的列的方法
Sep 11 Python
使用python打印十行杨辉三角过程详解
Jul 10 #Python
python简单实现矩阵的乘,加,转置和逆运算示例
Jul 10 #Python
Python中新式类与经典类的区别详析
Jul 10 #Python
详解Pandas之容易让人混淆的行选择和列选择
Jul 10 #Python
python的几种矩阵相乘的公式详解
Jul 10 #Python
Python内存管理实例分析
Jul 10 #Python
OpenCV 边缘检测
Jul 10 #Python
You might like
PHP中函数内引用全局变量的方法
2008/10/20 PHP
php 学习资料零碎东西
2010/12/04 PHP
PHP截取指定图片大小的方法
2014/12/10 PHP
PHP解析url并得到url参数方法总结
2018/10/11 PHP
asp 取文本框名称代码
2008/12/02 Javascript
Jquery实现网页跳转或用命令打开指定网页的解决方法
2013/07/09 Javascript
JS实现文字链接感应鼠标淡入淡出改变颜色的方法
2015/02/26 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
2015/09/30 Javascript
jQuery ajax请求返回list数据动态生成input标签,并把list数据赋值到input标签
2016/03/29 Javascript
jquery 获取select数组与name数组长度的实现代码
2016/06/20 Javascript
用Vue.js实现监听属性的变化
2016/11/17 Javascript
jQuery Masonry瀑布流插件使用方法详解
2017/01/18 Javascript
js Canvas绘制圆形时钟教程
2017/02/06 Javascript
Vue实现virtual-dom的原理简析
2017/07/10 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
2017/09/22 jQuery
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
Angular6中使用Swiper的方法示例
2018/07/09 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
2018/10/12 Javascript
JavaScript使用ul中li标签实现删除效果
2019/04/15 Javascript
Vue项目路由刷新的实现代码
2019/04/17 Javascript
使用 Jest 和 Supertest 进行接口端点测试实例详解
2020/04/25 Javascript
vue下拉刷新组件的开发及slot的使用详解
2020/12/23 Vue.js
[51:29]Alliance vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Cython 三分钟入门教程
2009/09/17 Python
使用Python对MySQL数据操作
2017/04/06 Python
pandas中的数据去重处理的实现方法
2020/02/10 Python
Python绘图之二维图与三维图详解
2020/08/04 Python
Html5原创俄罗斯方块(基于canvas)
2019/01/07 HTML / CSS
Gerry Weber德国官网:优质女性时装,德国最大的时装公司之一
2019/11/02 全球购物
Linux Interview Questions For software testers
2012/06/02 面试题
EJB2和EJB3在架构上的不同点
2014/09/29 面试题
公司开业庆典主持词
2014/03/21 职场文书
放飞中国梦演讲稿
2014/04/23 职场文书
三好学生先进事迹材料
2014/08/28 职场文书
领导干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用
2021/06/30 SQL Server