浅谈python之新式类


Posted in Python onAugust 12, 2018

前言

本文中代码运行的python版本一律采取2.7.13

科普:

经典类:classic class

新式类:new-style class

  1. python2.2 之前并没有新式类
  2. python2.2-2.7 新式类与经典类并存, 默认使用经典类, 除非显式继承object
  3. python3.X 中去除了经典类, 用户定义的所有类都隐式继承自object

 如何使用新式类

class New(object): # 显式继承object类
 pass

class Old: 
 pass
  
class Old2():
 pass

上述代码中的3种定义类的方法, 只有第一种方法定义的是新式类.

新式类VS经典类 

新式类与经典类最主要的区别在于继承顺序, 事实上, 对于用户定义的每一个类, python 都会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,它代表了类继承的顺序, 而由于经典类与新式类采用的算法不一致, 相同的继承关系可能会出现不一样的MRO列表.

import inspect
class D:
  pass
 
class C(D):
  pass 
 
class B(D):
  pass
 
class A(B, C):
  pass  

print inspect.getmro(A)
# (<class __main__.A at 0x000000000322BB88>, 
# <class __main__.B at 0x000000000322B9A8>, 
# <class __main__.D at 0x000000000322BC48>, 
# <class __main__.C at 0x000000000322B948>)

class D(object):
  pass
 
class C(D):
  pass
 
class B(D):
  pass
 
class A(B, C):
  pass

print inspect.getmro(A)

# (<class '__main__.A'>, 
<class '__main__.B'>, 
<class '__main__.C'>, 
<class '__main__.D'>, 
<type 'object'>)

可以看到, 经典类的MRO顺序A-B-D-C 与新式类的MRO顺序 A-B-C-D-object 是存在差异的, 这可能会是我们日常会遇到的坑.

而除了继承顺序的差异, 新式类还添加了内置属性__slots__

一般来说, 每个实例都有一个字典来管理实例的属性, 我们可以用__dict__ 来查看(__dict__并不保存类属性),它允许我们动态地修改实例的属性, 但是这也意味着每个实例都会有1个独立的字典需要我们去维护, 当我们需要创建大量的实例时, 这个操作是十分消耗内存的.

当我们在定义类时添加了__slots__属性后, 对象在实例化时就不会创建字典来管理实例属性, 而实例只能定义在__slots__里边已经设定好的属性名, 不允许动态添加其他未在__slots__里定义的属性

class Student(object):
 __slots__ = ('id', 'name', 'gender')
 def exam(self):
  pass

s1 = Student()
'__dict__' in dir(s1) # False
s1.id = 10001
s1.class = 1 
# AttributeError: 'Student' object has no attribute 'class'

def func():
 pass

s1.exam = func 
# AttributeError: 'Student' object attribute 'f' is read-only

使用__slots__ 后我们不再能够动态地修改实例的属性, 那么使用__slots__究竟有什么好处呢?

优点:
 1.节省内存
 2.提高属性访问速度

缺点:
 1.不能动态修改实例属性

当然, 除了继承顺序和__slots__, 新式类添加了__getattribute__方法, 还修改了实例的类型

class New(object):
 pass
 
class Old:
 pass
 
new = New()
old = Old()
print(new)
# <__main__.New object at 0x0000000003262208>
print(old)
# <__main__.Old instance at 0x000000000321C6C8>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python遍历指定文件及文件夹的方法
May 09 Python
用python记录运行pid,并在需要时kill掉它们的实例
Jan 16 Python
利用python微信库itchat实现微信自动回复功能
May 18 Python
用Eclipse写python程序
Feb 10 Python
解决Python requests库编码 socks5代理的问题
May 07 Python
Django用户认证系统 Web请求中的认证解析
Aug 02 Python
Python第三方包PrettyTable安装及用法解析
Jul 08 Python
Python datetime 如何处理时区信息
Sep 02 Python
python利用platform模块获取系统信息
Oct 09 Python
只用50行Python代码爬取网络美女高清图片
Jun 02 Python
python全面解析接口返回数据
Feb 12 Python
python使用BeautifulSoup 解析HTML
Apr 24 Python
详解Django中类视图使用装饰器的方式
Aug 12 #Python
python中pip的安装与使用教程
Aug 10 #Python
python3判断url链接是否为404的方法
Aug 10 #Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
Aug 10 #Python
Selenium元素的常用操作方法分析
Aug 10 #Python
Selenium定位元素操作示例
Aug 10 #Python
判断python字典中key是否存在的两种方法
Aug 10 #Python
You might like
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
2013/06/03 PHP
CodeIgniter中实现泛域名解析
2014/07/19 PHP
php实现有趣的人品测试程序实例
2015/06/08 PHP
PHP微信公众号自动发送红包API
2016/06/01 PHP
使用Yii2实现主从数据库设置
2016/11/20 PHP
ArrayList类(增强版)
2007/04/04 Javascript
jquery使用jquery.zclip插件复制对象的实例教程
2013/12/04 Javascript
浅析JavaScript中两种类型的全局对象/函数
2013/12/05 Javascript
Jquery 切换不同图片示例代码
2013/12/05 Javascript
JS使用replace()方法和正则表达式进行字符串的搜索与替换实例
2014/04/10 Javascript
Js和JQuery获取鼠标指针坐标的实现代码分享
2015/05/25 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
Extjs 中的 Treepanel 实现菜单级联选中效果及实例代码
2017/08/22 Javascript
JS选取DOM元素常见操作方法实例分析
2018/12/10 Javascript
javascript 原型与原型链的理解及实例分析
2019/11/23 Javascript
javascript设计模式 ? 建造者模式原理与应用实例分析
2020/04/10 Javascript
浅谈vue中$bus的使用和涉及到的问题
2020/07/28 Javascript
JS时间戳与日期格式互相转换的简单方法示例
2021/01/30 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
Python编程使用*解包和itertools.product()求笛卡尔积的方法
2017/12/18 Python
Python pyinotify模块实现对文档的实时监控功能方法
2018/10/13 Python
python pandas实现excel转为html格式的方法
2018/10/23 Python
python调用c++传递数组的实例
2019/02/13 Python
Python将列表数据写入文件(txt, csv,excel)
2019/04/03 Python
python语言元素知识点详解
2019/05/15 Python
Django中的cookie和session
2019/08/27 Python
Python异步编程之协程任务的调度操作实例分析
2020/02/01 Python
Python如何实现爬取B站视频
2020/05/20 Python
HTML5 预加载让页面得以快速呈现
2013/08/13 HTML / CSS
丝芙兰波兰:Sephora.pl
2018/03/25 全球购物
Boolean b = new Boolean(“abcde”); 会编译错误码
2013/11/27 面试题
北京振戎融通Java面试题
2015/09/03 面试题
企业文明单位申报材料
2014/05/16 职场文书
党员转正大会主持词
2015/07/02 职场文书
创业计划书之书店
2019/09/10 职场文书
Moment的feature导致线上bug解决分析
2022/09/23 Javascript