浅谈python之新式类
前言
本文中代码运行的python版本一律采取2.7.13
科普:
经典类:classicclass
新式类:new-styleclass
- python2.2之前并没有新式类
- python2.2-2.7新式类与经典类并存,默认使用经典类,除非显式继承object
- python3.X中去除了经典类,用户定义的所有类都隐式继承自object
如何使用新式类
classNew(object):#显式继承object类 pass classOld: pass classOld2(): pass
上述代码中的3种定义类的方法,只有第一种方法定义的是新式类.
新式类VS经典类
新式类与经典类最主要的区别在于继承顺序,事实上,对于用户定义的每一个类,python都会计算出一个方法解析顺序(MethodResolutionOrder,MRO)列表,它代表了类继承的顺序,而由于经典类与新式类采用的算法不一致,相同的继承关系可能会出现不一样的MRO列表.
importinspect classD: pass classC(D): pass classB(D): pass classA(B,C): pass printinspect.getmro(A) #(, # , # , # ) classD(object): pass classC(D): pass classB(D): pass classA(B,C): pass printinspect.getmro(A) #( , , , , )
可以看到,经典类的MRO顺序A-B-D-C与新式类的MRO顺序A-B-C-D-object是存在差异的,这可能会是我们日常会遇到的坑.
而除了继承顺序的差异,新式类还添加了内置属性__slots__
一般来说,每个实例都有一个字典来管理实例的属性,我们可以用__dict__来查看(__dict__并不保存类属性),它允许我们动态地修改实例的属性,但是这也意味着每个实例都会有1个独立的字典需要我们去维护,当我们需要创建大量的实例时,这个操作是十分消耗内存的.
当我们在定义类时添加了__slots__属性后,对象在实例化时就不会创建字典来管理实例属性,而实例只能定义在__slots__里边已经设定好的属性名,不允许动态添加其他未在__slots__里定义的属性
classStudent(object): __slots__=('id','name','gender') defexam(self): pass s1=Student() '__dict__'indir(s1)#False s1.id=10001 s1.class=1 #AttributeError:'Student'objecthasnoattribute'class' deffunc(): pass s1.exam=func #AttributeError:'Student'objectattribute'f'isread-only
使用__slots__后我们不再能够动态地修改实例的属性,那么使用__slots__究竟有什么好处呢?
优点:
1.节省内存
2.提高属性访问速度
缺点:
1.不能动态修改实例属性
当然,除了继承顺序和__slots__,新式类添加了__getattribute__方法,还修改了实例的类型
classNew(object): pass classOld: pass new=New() old=Old() print(new) #<__main__.Newobjectat0x0000000003262208> print(old) #<__main__.Oldinstanceat0x000000000321C6C8>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。